如何区分Spring Rest Controller中部分更新的null值和未提供值 [英] 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 ... */
}
My 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).
具有null属性的请求
{"firstName": "John", "lastName": null}
预期行为:更新 firstName =John
并设置 lastName = null
。
Expected behaviour: update firstName="John"
and set lastName=null
.
我无法区分这两种情况,因为DTO中的 lastName
始终设置为 null
由Jackson。
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的集合方法,将属性名称和值放到
changedAttrs(因为当
属性的值为null或不为null时,spring将调用该集合。) - 第三,遍历地图。
这篇关于如何区分Spring Rest Controller中部分更新的null值和未提供值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!