我正在制作一个Spring Boot应用程序。我在那里有一个实体:
@Entity
public class Employee {
@NotNull
private Category category;
// Education related fields
@NotNull
private Education education;
@NotBlank
private String eduName;
@NotNull
private LocalDate eduGraduationDate;
// other fields, getters, setters ...
}
正如您所看到的,我在那里有验证注释。但在我的应用程序中,我需要部分更新字段,例如,客户端希望单独更新Education
字段和Category
字段。
问题是,我不能使用PUT请求来做这件事,因为它会更新整个对象。如果Category
字段实际上是null
,而我只想更新Education
字段,我将得到ConstraintViolationException
,因为Category
字段是null
。但它是null
,我希望它进一步成为null
。
我可以使用PATCH请求来做到这一点:
@PatchMapping(path = "/{id}", consumes = "application/merge-patch+json")
public ResponseEntity<Employee> patchEmployee(@PathVariable Long id, @RequestBody JsonMergePatch jsonMergePatch) throws JsonPatchException, JsonProcessingException {
Employee employee = employeeDataService.findById(id).orElseThrow(() -> new ResourceNotFoundException("Employee not exist: id = " + id));
Employee employeePatched = applyPatchToEmployee(jsonMergePatch, employee);
return ResponseEntity.ok(employeeDataService.save(employeePatched));
}
private Employee applyPatchToEmployee(JsonMergePatch jsonMergePatch, Employee targetEmployee) throws JsonPatchException, JsonProcessingException {
JsonNode patched = jsonMergePatch.apply(objectMapper.convertValue(targetEmployee, JsonNode.class));
return objectMapper.treeToValue(patched, Employee.class);
}
但问题是:如何部分验证字段
例如,如果我发送带有正文的PATCH请求:
{
"education":"HIGHER",
"eduName":"MIT",
"eduGraduationDate":"2020-05-05"
}
如何仅验证这3个字段?不是整个Employee
对象?在这个例子中,正如我上面提到的,我希望Category
字段是null
,如果它不包括在补丁中,我不想验证它。
也许有一些更好的方法来部分更新实体,如果是的话——哪一种?
您可以创建一个新的DTO对象,其中只有您想为PATCH调用包括的字段,如
EmployeePatchDto
public class EmployeePatchDto {
// Education related fields
@NotNull
private Education education;
@NotBlank
private String eduName;
@NotNull
private LocalDate eduGraduationDate;
// other fields, getters, setters ...
}
但现在您仍然需要确保在调用API时考虑到这些验证。此外,您可以选择使用@Valid
在控制器方法级别验证您的DTO类,如下所示,
public ResponseEntity<Employee> patchEmployee(@PathVariable Long id, @Valid @RequestBody EmployeePatchDto employeeDto) throws JsonPatchException, JsonProcessingException {
我把这个资源留给你。读这个。