【问题标题】:How to limit fields that map in @RequestBody如何限制在@RequestBody 中映射的字段
【发布时间】:2020-02-20 01:49:13
【问题描述】:

我正在尝试实现一个非常基本的 Spring Boot Web 应用程序。我在 @RequestBody 的帮助下将 JSON 对象映射到实体(如客户实体)。

addCustomer 方法中,我只想绑定/映射 firstNamelastName 字段并忽略 Id字段,即使客户端响应 JSON 具有该字段。

updateCustomer 方法中,我需要映射包括 Id 在内的所有字段,因为我需要 Id 字段来更新实体。

如何在@RequestBody的自动映射过程中忽略一些或一个字段。

@RestController
@RequestMapping("/customer-service")
public class CustomerController {
    @Autowired
    CustomerServiceImpl customerService; 

    //This method has to ignore "id" field in mapping to newCustomer
    @PostMapping(path = "/addCustomer")
    public void addCustomer(@RequestBody Customer newCustomer) {
        customerService.saveCustomer(newCustomer);
    }

    //This method has to include "id" field as well to updatedCustomer
    @PostMapping(path = "/updateCustomer")
    public void updateCustomer(@RequestBody Customer updatedCustomer) {
        customerService.updateCustomer(updatedCustomer);
    }
}
@Entity
@Table(name = "CUSTOMER")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long cusId;

    private String firstName;
    private String lastName;

    //Default Constructor and getter-setter methods after here
}

【问题讨论】:

    标签: spring-boot jackson spring-restcontroller


    【解决方案1】:

    您可以使用多个@JsonViews 在每种方法中使用不同的映射。

    1. 定义视图:
    public class Views {
        public static class Create {
        }
    }
    
    1. 选择应在每个视图中使用哪些字段:
    @Entity
    @Table(name = "CUSTOMER")
    public class Customer {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long cusId;
    
        @JsonView(Views.Create.class)
        private String firstName;
        @JsonView(Views.Create.class)
        private String lastName;
        ...
    }
    
    1. 告诉 Spring MVC 在特定方法中使用这个视图:
    @PostMapping(path = "/addCustomer")
    public void addCustomer(@RequestBody @JsonView(Views.Create.class) Customer newCustomer) {
        customerService.saveCustomer(newCustomer);
    }
    

    【讨论】:

    • 感谢它解决了忽略“Id”字段的问题,即使用户在“addCustomer()”方法中提供了它。但是如果“Id”字段为空,有没有办法让“updateCustomer()”方法抛出异常?因为如果用户不提供,我现在拥有的代码会将“Id”字段映射为 null。还是在“updateCustomer()”中检查“Id”的内容并在方法中手动处理更好?
    • 您可以使用来自 JSR 303 @NotNull(group = ...) 的验证组,但是使用 json 视图和验证组已经变得相当复杂。也许您可以考虑将请求正文绑定到单独的对象,然后将它们映射到客户。这意味着一些重复,但我认为代码会更容易推理。
    【解决方案2】:

    TL;DR:使用以下之一:

    • @JsonIgnoreProperties("fieldname") 在你的课堂上。
    • @JsonIgnore 在您的字段上忽略其映射。

    例子:

    @Getter
    @Setter
    @JsonIgnoreProperties("custId")
    public class Customer {
    
    @JsonIgnore
    private String custId;
    private String firstName;
    private String lastName;
    
    }
    

    但是,由于您拥有相同的 POJO,它将跳过两个请求的“custId”映射。

    AFAIK,您的@PostMapping(添加客户)不应该收到custId 值,因此它将被动态设置为null 或默认值。在创建用户的同时,您还应该为它创建 ID 或让数据库来处理它。

    对于@PutMapping(更新用户),您必须获取可用于识别用户然后进行更新的 ID 值。

    【讨论】:

    • 如果 JsonIgnore 忽略两种方法中的字段,则解决方案可能不完全匹配。是的,正如您所说,在“AddingCustomer”方法中,我想忽略“Id”,因为它是由休眠创建的。在“updatingCustomer”方法中,我需要映射“Id”字段,因为我需要它来进行更新。
    猜你喜欢
    • 2019-07-14
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2018-09-08
    • 2016-02-03
    • 2013-11-03
    • 2020-03-01
    相关资源
    最近更新 更多