如何在 Spring Rest Controller 中区分部分更新的空值和未提供值 [英] How to distinguish between null and not provided values for partial updates in Spring Rest Controller

查看:47
本文介绍了如何在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆