问题描述
我试图在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值和未提供值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!