本文介绍了如何区分Spring Rest Controller中部分更新的null值和未提供值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

11-02 11:11