我试图在控制器方法中使用spring boot 2.5.3来更新实体。
http://localhost:5000/api/v1/student/1
具有以下有效负载。
{
"name":"abc",
"email":"abc@email.com",
"dob":"2000-06-14"
}
这些值不更新。当我使用调试器检查它们时,它们得到空值。这是我的控制器方法。
@PutMapping(path = "/{id}")
public ResponseEntity<?> updateStudent(@PathVariable("id") Long id, @RequestParam(required = false) String name, @RequestParam(required = false) String email) {
Student savedStudent = studentService.updateStudent(id, name, email);
return ResponseEntity.ok(savedStudent);
}
电子邮件和姓名可选。
调试器:name:null,email:null
。为什么它们得到的是空值?从控制器传递值的正确方法是什么?
@Transactional
// We are not using any query from the repository because we have the service method with transactional annotation.
public Student updateStudent(Long studentId, String name, String email) {
Student student = studentRepository.findById(studentId).orElseThrow(()->new EntityNotFoundException("Student with id " + studentId + " does not exists."));
if (name!= null && name.length()>0 && !Objects.equals(name,student.getName())){
student.setName(name);
}
if (email!= null && email.length()>0 && !Objects.equals(email,student.getEmail())){
Optional<Student> optionalStudent = studentRepository.findStudentByEmail(email);
if (optionalStudent.isPresent()){
throw new IllegalStateException("Email is already taken");
}
student.setEmail(email);
}
System.out.println(student);
Student savedStudent= studentRepository.save(student);
return savedStudent;
}
{
"name":"abc",
"email":"abc@email.com",
"dob":"2000-06-14"
}
这不是请求参数,而是请求体。您需要创建一个类并使用@RequestBody
注释。
@Data
public class UpdateStudentRequest {
private String id;
private String name;
private String email;
}
@PutMapping(path = "/{id}")
public ResponseEntity<?> updateStudent(@PathVariable("id") Long id, @RequestBody UpdateStudentRequest request) {
Student savedStudent = studentService.updateStudent(
request.getId(), request.getName(), request.getEmail());
return ResponseEntity.ok(savedStudent);
}
如果你想发送请求参数为…URL参数:
http://localhost:5000/api/v1/student/1?name=abc&email=abc@email.com
您没有将其作为参数发送(在?
之后)。http://localhost:5000/api/v1/student/1?name=John
可以做到。
由于您正在POST
使用内容主体的HTTP请求(在您的情况下是JSON),您需要使用@RequestBody
注释来映射主体:
@PutMapping(path = "/{id}")
public ResponseEntity<?> updateStudent(@PathVariable("id") Long id, @RequestBody StudentDTO student) {
Student savedStudent = studentService.updateStudent(
id, student.getName(), student.getEmail());
return ResponseEntity.ok(savedStudent);
}
StudentDTO
将是一个轻量级类型,反映您的输入有效负载:
public class StudentDTO {
private String name;
private String email;
private String dob;
// setters and getters
}
否则,要保留您的RestController
签名并使用@RequestParam
电子域,您应该发送以下形状的请求:
http://localhost:5000/api/v1/student/1?name=abc&email=abc@email.com&dob=2000-06-14