当前位置: 首页 > 面试题库 >

如何在Spring Rest Controller中区分null和未提供的值以进行部分更新

狄易安
2023-03-14
问题内容

我试图在Spring Rest Controller中使用PUT请求方法部分更新实体时区分空值和未提供值。

以以下实体为例:

@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数据):

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
}

我使用的DTO:

private class PersonDTO {
    private String firstName;
    private String lastName;

    /* getters and setters ... */
}

我的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不变)。

具有空属性的请求

{"firstName": "John", "lastName": null}

预期行为:更新firstName="John"并设置lastName=null

我无法区分这两种情况,因为lastName在DTO中,总是null由Jackson 设置。

注意:我知道REST最佳实践(RFC 6902)建议使用PATCH而不是PUT进行部分更新,但是在我的特定情况下,我需要使用PUT。


问题答案:

实际上,如果忽略验证,您可以像这样解决您的问题。

   public class BusDto {
       private Map<String, Object> changedAttrs = new HashMap<>();

       /* getter and setter */
   }
  • 首先,为您的dto编写一个超类,例如BusDto。
  • 其次,更改dto来扩展超类,并更改dto的set方法,以将属性名称和值放置到changedAttrs中(因为当属性具有null值或非null值时,spring都会调用set)。
  • 第三,遍历地图。


 类似资料:
  • 当在Spring Rest Controller中使用PUT请求方法部分更新实体时,我试图区分空值和未提供的值。 考虑以下实体,例如: 我的个人存储库(Spring Data): 我使用的DTO: 我的Spring RestController: 有丢失财产的请求 预期行为:更新(保持不变)。 具有null属性的请求 预期行为:更新并设置。 我无法区分这两种情况,因为Jackson总是将DTO中的

  • 问题内容: 愚蠢但简单的示例:假设我有一个表“ Item”,其中保存接收到的项目的总数。 项目名称是此处的主键。每当我收到数量为X的物料A时,如何实现以下目标。 如果该商品不存在,则为商品A插入一个新的摘要,并将库存商品设置为X;如果存在一条记录,其中库存商品为Y,则库存商品的新值为(X + Y) 我的问题是我的实际表中有多个列。在更新部分中编写多个select语句是一个好主意吗? 我当然可以用代

  • 如何区分未发送的值和空值?如何检测客户端是否发送了空字段或跳过字段?

  • 我正试图在应用程序处于退出状态时从firebase保存一个通知到redux。 但是我需要在app.js中这样做,当我甚至不在组件上时,我如何分派redux操作呢? 这就是我要做的

  • 问题内容: 我有一个类似于http://drive.google.com的链接,并且我想在该链接之外匹配“ google”。 我有: 但这仅在整个文本为“ google”时才匹配(不区分大小写,因此也匹配Google或GooGlE等)。如何匹配另一个字符串中的“ google”? 问题答案: 关键是您使用的ElasticSearch正则表达式需要 完整的字符串匹配 : Lucene的模式总是锚定的

  • 本文向大家介绍区分MySQL中的空值(null)和空字符(''),包括了区分MySQL中的空值(null)和空字符('')的使用技巧和注意事项,需要的朋友参考一下 日常开发中,一般都会涉及到数据库增删改查,那么不可避免会遇到Mysql中的NULL和空字符。 空字符('')和空值(null)表面上看都是空,其实存在一些差异: 定义: 空值(NULL)的长度是NULL,不确定占用了多少存储空间,但是占