如何在控制器中传递非空值@RequestParameter?

How to pass not null values @RequestParameter in controller?

我正在尝试通过在控制器方法中使用 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"
}

这不是请求参数,而是请求正文。您需要创建一个 class 并使用 @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 签名并使用 @RequestParametrized 字段,您应该发送以下格式的请求:

http://localhost:5000/api/v1/student/1?name=abc&email=abc@email.com&dob=2000-06-14