[英]My update function doesn't work : Spring CRUD API
我正在創建一個帶有 Spring 的 CRUD API 來管理學生。 這是我的服務:
package com.example.demo.student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Service
public class StudentService {
private final StudentRepository studentRepository;
@Autowired
public StudentService(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
public List<Student> getStudents(){
return studentRepository.findAll();
}
public void addNewStudent(Student student) {
Optional<Student> studentByName = studentRepository.findStudentByName(student.getName());
if(studentByName.isPresent()){
try {
throw new Exception("name taken");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
studentRepository.save(student);
}
public void deleteStudent(Long studentId) {
boolean exists = studentRepository.existsById(studentId);
if (!exists){
throw new RuntimeException("student with id" + studentId + " does not exist.");
}
studentRepository.deleteById(studentId);
}
@Transactional
public Student updateStudent(Long studentId, String name) {
Student student = studentRepository.findById(studentId).orElseThrow(() -> new RuntimeException(
"student with Id" + studentId + " does not exist"
)
);
if(name != null && name.length() > 0 && !Objects.equals(student.getName(), name)){
student.setName(name);
return studentRepository.save(student);
}
return student;
}
public Optional<Student> getStudent(Long studentId) {
Student student = studentRepository.findById(studentId).orElseThrow(() -> new RuntimeException(
"student with Id" + studentId + " does not exist"
)
);
return studentRepository.findById(studentId);
}
}
還有我的 controller:
package com.example.demo.student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping(path="api/student")
public class StudentController {
private final StudentService studentService;
@Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
@GetMapping
public List<Student> getStudents(){
return studentService.getStudents();
}
@GetMapping(path="/{studentId}")
public Optional<Student> getStudent(@PathVariable("studentId")Long studentId){
return studentService.getStudent(studentId);
}
@PostMapping
public void registerNewStudent(@RequestBody Student student){
studentService.addNewStudent(student);
}
@DeleteMapping(path="{studentId}")
public void deleteStudent(@PathVariable("studentId")Long studentId){
studentService.deleteStudent(studentId);
}
// only update name
@PutMapping(path="{studentId}")
public void updateStudent(
@PathVariable("studentId")Long studentId,
@RequestParam(required = false) String name)
{
studentService.updateStudent(studentId, name );
}
}
But when I go on postman, and try to update for example student 3 with this url: http://localhost:8080/api/student/3, it doesn't change anything, even if the response is 1.
任何人都可以幫助我嗎? 提前致謝
您忽略了隨 PUT 發送的有效負載。 在 PUT 端點的 Controller 中,您沒有使用@RequestBody
。
您僅使用@RequestParam
注釋。 因此,使用您編寫的代碼,您只能通過將其作為 URL 的一部分發送來更改名稱。
然而,在您發送的請求中,您沒有指定name @RequestParam
。 如果你想看到你的代碼正常工作,只需發送一個 PUT 到這個 URL: localhost:8080/api/student/3?name=jean
。
在我看來,您應該刪除name @RequestParam
並像在 POST 中那樣添加@RequestBody
。
我不會在同一個端點中混合 @RequestParam 和 @PathVariable。 即便如此,嘗試調用
PUT http://localhost:8080/api/student/3?name=Jones
那樣有用嗎?
或將您的 controller 方法簽名更改為
@PutMapping("/{studentId}/{name}")
public void updateStudent( @PathVariable("studentId")Long studentId, @PathVariable("name") String name)
...然后打電話
PUT http://localhost:8080/api/student/3/Jones
這可能是相切的,但我會抽象出一個接口 IStudentService(或其他命名約定),只有方法聲明,沒有實現。 然后將 class 更新為
public class StudentService implements IStudentService;
假設 StudentRepository 是一個 Jpa/CrudRepository 接口,那么在 StudentService 中你所需要的就是
@Autowired StudentRepository studentRepository;
您不需要那種冗長的構造函數注入。 在 controller 中,您只需要
@Autowired IStudentService studentService;
(接口的名稱不是實現類)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.