英文:
SpringBoot: Serving JSON requests with some fields missing
问题
我正在构建一个POJO类,以匹配在基于SpringBoot实现的REST API中收到的一些请求。其中一些数据**必须**由客户端提供给我,否则我甚至不愿意处理该请求。为了确保客户端至少提供给我我**绝对**需要的内容,我使用了Lombok的`@NonNull`注解:
```java
@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;
}
}
(我完全理解将货币数量处理为Double
是不推荐的;这只是一个示例。)
从控制器处理这个类就像是在/products
端点上添加一个监听器一样简单:
@PostMapping(value = "/products")
public Product postProduct(@RequestBody ProductRequestBody newProduct)
{
// ...
// 适当地处理请求
// ...
}
现在,如果我收到一个POST请求,其中一个未被标记为@NonNull
的字段为null
,就像下面这样,我可以毫无问题地处理它:
{
"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,
// 这个载荷中没有"description"字段
}
我该如何实现这一点?代码越少越好,一如既往。
<details>
<summary>英文:</summary>
I'm building a POJO class to match some requests coming my way in a REST API implemented on SpringBoot. Some of the data _has_ to be given to me, otherwise I am not willing to even serve the request. To make sure the client gives me at least what I _absolutely_ need, I have used Lombok's `@NonNull`:
```java
@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;
}
}
(I completely understand that handling monetary quantities as Double
s is a no-no; this is just an example.
Processing this from my controller is as easy as a listener on the /products
endpoint like so:
@PostMapping(value = "/products")
public Product postProduct(@RequestBody ProductRequestBody newProduct)
{
// ...
// Serve the request appropriately
// ...
}
Now, if I receive a POST request with a null
field that has not been marked as @NonNull
, like the following, I can serve it without issue:
{
"name": "Some Product Name",
"category": "Some Product Category",
"cost" : 10.0,
"description": null
}
My goal, however, is to be able to handle JSON
requests that simply don't even have the fields they don't care about. That is, I want to be able to serve the following as well, and I currently can't:
{
"name": "Some Product Name",
"category": "Some Product Category",
"cost" : 10.0,
// No "description" field in this payload
}
How could I go about doing this? The less code, the better, as always.
答案1
得分: 2
如果您使用spring-boot和lombok,您可以将您的类简化为以下形式:
@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;
}
如果没有提供name、category或cost,则会返回400,否则返回200。
英文:
If you use spring-boot and lombok you can simplify your class to be like this:
@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;
}
it will return 400 if name, category or cost will be not provided and 200 otherwise.
答案2
得分: 1
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 handles serializing and deserializing json without any issue.
You should let spring handle it.
You can try the following.
@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;
}
If you really want to follow the pattern of creating a constructor, then you should create a constructor with only the @NonNull
fields and create getter of others (lombok
handles that for you). If you want to add @JsonProperty
then you need to create separate 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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论