如何在 Spring Rest Controller 中区分部分更新的空值和未提供值 [英] How to distinguish between null and not provided values for partial updates in Spring Rest Controller
问题描述
在 Spring Rest Controller 中使用 PUT 请求方法部分更新实体时,我试图区分空值和未提供的值.
I'm trying to distinguish between null values and not provided values when partially updating an entity with PUT request method in Spring Rest Controller.
以以下实体为例:
@Entity
private class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/* let's assume the following attributes may be null */
private String firstName;
private String lastName;
/* getters and setters ... */
}
我的个人存储库(Spring 数据):
My Person repository (Spring Data):
@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
}
我使用的 DTO:
private class PersonDTO {
private String firstName;
private String lastName;
/* getters and setters ... */
}
我的 Spring RestController:
My Spring RestController:
@RestController
@RequestMapping("/api/people")
public class PersonController {
@Autowired
private PersonRepository people;
@Transactional
@RequestMapping(path = "/{personId}", method = RequestMethod.PUT)
public ResponseEntity<?> update(
@PathVariable String personId,
@RequestBody PersonDTO dto) {
// get the entity by ID
Person p = people.findOne(personId); // we assume it exists
// update ONLY entity attributes that have been defined
if(/* dto.getFirstName is defined */)
p.setFirstName = dto.getFirstName;
if(/* dto.getLastName is defined */)
p.setLastName = dto.getLastName;
return ResponseEntity.ok(p);
}
}
缺少属性的请求
{"firstName": "John"}
预期行为:更新 firstName="John"
(保持 lastName
不变).
Expected behaviour: update firstName= "John"
(leave lastName
unchanged).
请求为空属性
{"firstName": "John", "lastName": null}
预期行为:更新 firstName="John"
并设置 lastName=null
.
Expected behaviour: update firstName="John"
and set lastName=null
.
我无法区分这两种情况,因为 DTO 中的lastName
总是被 Jackson 设置为 null
.
I cannot distinguish between these two cases, sincelastName
in the DTO is always set to null
by Jackson.
注意:我知道 REST 最佳实践 (RFC 6902) 建议使用 PATCH 而不是 PUT 进行部分更新,但在我的特定场景中,我需要使用 PUT.
推荐答案
其实,如果忽略验证,你可以这样解决你的问题.
Actually,if ignore the validation,you can solve your problem like this.
public class BusDto {
private Map<String, Object> changedAttrs = new HashMap<>();
/* getter and setter */
}
- 首先,为您的 dto 编写一个超类,例如 BusDto.
- 第二,改变你的dto来扩展超类,并改变dto 的 set 方法,将属性名称和值放入changedAttrs(因为弹簧会在无论是否为空,属性都有值).
- 第三,遍历地图.
这篇关于如何在 Spring Rest Controller 中区分部分更新的空值和未提供值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!