SpringBoot:服务 JSON 请求但缺少某些字段

SpringBoot: Serving JSON requests with some fields missing

我正在构建一个 POJO class 来匹配我在 SpringBoot 上实现的 REST API 中的一些请求。有些数据给我,不然我连请求都不愿意服务。为了确保客户至少给我 绝对 需要的东西,我使用了 Lombok 的 @NonNull:

@Data
public class ProductRequestBody implements Serializable
{
    private String name;
    private String category;
    private String description;
    private String abbreviation;
    private String labelColor;
    private Double cost;

    public ProductRequestBody()
    {
    }

    @JsonCreator
    public ProductRequestBody(@NonNull @JsonProperty("name") String name,
                              @NonNull @JsonProperty("category") String category,
                              @JsonProperty("description") String description,
                              @NonNull @JsonProperty("cost") Double cost)
    {
        this.name = name;
        this.category = category;
        this.description = description;
        this.cost = cost;
    }
}

(我完全理解将货币数量处理为 Doubles 是一个禁忌;这只是一个例子。

从我的控制器处理这个就像 /products 端点上的侦听器一样简单,如下所示:

@PostMapping(value = "/products")
public Product postProduct(@RequestBody ProductRequestBody newProduct)
{
   // ... 
   // Serve the request appropriately
   // ... 
}

现在,如果我收到一个 POST 请求,其中 null 字段 被标记为 @NonNull,如下所示,我可以毫无问题地提供服务:

{
        "name": "Some Product Name",
        "category": "Some Product Category", 
        "cost" : 10.0,
        "description": null
}

但是,我的目标是能够处理 JSON 甚至没有他们不关心的字段的请求。也就是说,我也希望能够提供以下服务,而目前我还不能:

{
        "name": "Some Product Name",
        "category": "Some Product Category", 
        "cost" : 10.0,
        // No "description" field in this payload
}

我该怎么做呢?一如既往,代码越少越好。

Spring 处理序列化和反序列化 json 没有任何问题。 你应该让 spring 处理它。
您可以尝试以下方法。

@Data
public class ProductRequestBody implements Serializable {
    @NonNull
    private String name;
    @NonNull
    private String category;
    private String description;
    private String abbreviation;
    private String labelColor;
    @NonNull
    private Double cost;
}

如果您真的想遵循创建构造函数的模式,那么您应该创建一个仅包含 @NonNull 字段的构造函数并创建 getter 个其他字段(lombok 处理为你)。如果你想添加 @JsonProperty 那么你需要创建单独的 getter.

@Data                                                                                
public class ProductRequestBody implements Serializable                              
{                                                                                    
    private String name;                                                             
    private String category;                                                         
    private String description;                                                      
    private String abbreviation;                                                     
    private String labelColor;                                                       
    private Double cost;                                                             
                                                                                     
    public ProductRequestBody()                                                      
    {                                                                                
    }                                                                                
                                                                                     
    @JsonCreator                                                                     
    public ProductRequestBody(@NonNull @JsonProperty("name") String name,            
                              @NonNull @JsonProperty("category") String category,    
                              @NonNull @JsonProperty("cost") Double cost)            
    {                                                                                
        this.name = name;                                                            
        this.category = category;                                                    
        this.cost = cost;                                                            
    }                                                                                
                                                                                     
    @JsonProperty("description")                                                     
    public String getDescription() {                                                 
        return description;                                                          
    }                                                                                
}                                                                                    
                                                                                     

如果您使用 spring-boot 和 lombok,您可以将 class 简化为如下所示:

@Data
public class ProductRequestBody implements Serializable {

    @NonNull
    private String name;

    @NonNull
    private String category;

    @NonNull
    private Double cost;

    private String description;
    private String abbreviation;
    private String labelColor;
}

如果未提供名称、类别或费用,它将 return 400,否则为 200。