最近我將我的專案從 Spring Boot 2.1.0 更新到 Spring Boot 2.5.6。從那時起,我看到了 JSON 序列化的差異。
為了區分情況(a)任何值,(b)顯式 null和(c)沒有我使用的值java.util.Optional和杰克遜的@JsonInclude(NON_NULL)注釋。此外,我使用 Spring Data JPA 的投影模式來定義 JSON 格式,如下所示:
public interface MyProjection {
@JsonInclude(Include.NON_NULL)
Optional<String> getMyAttribute();
}
這與 Spring Boot 2.1.0 完美配合。
| 欄位值 | 渲染的 JSON |
|---|---|
Optional.of("something") |
{ "myAttribute": "something" } |
Optional.empty() |
{ "myAttribute": null } |
null |
{} |
截至目前(在我更新到 Spring Boot 2.5.6 之后)null呈現如下Optional.empty():
| 欄位值 | 渲染的 JSON |
|---|---|
Optional.of("something") |
{ "myAttribute": "something" } |
Optional.empty() |
{ "myAttribute": null } |
null |
{ "myAttribute": null } |
我的第一個假設是 JacksonNON_NULL不再與Optional. 但事實并非如此。正如@Pedro 所說,它作業正常。經過一番調查,我發現 SpringProjectionFactory似乎處理null不同的值。它轉換null為Optional.empty(),而它以前沒有這樣做。
我想恢復舊的行為。有誰知道如何防止 Spring 將空值轉換為空的 Optionals 而將其保留為空值?是否有新的默認配置?我沒有找到。
uj5u.com熱心網友回復:
經過幾次搜索,我找到了感興趣的測驗用例。
以下是 jackson 專案中可選的測驗用例的摘錄:
public void testConfigAbsentsAsNullsTrue() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module().configureAbsentsAsNulls(true));
OptionalData data = new OptionalData();
String value = mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).writeValueAsString(data);
assertEquals("{}", value);
}
public void testConfigAbsentsAsNullsFalse() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module().configureAbsentsAsNulls(false));
OptionalData data = new OptionalData();
String value = mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).writeValueAsString(data);
assertEquals("{\"myString\":null}", value);
}
class OptionalData {
public Optional<String> myString = Optional.empty();
}
單元測驗可選鏈接:
https://github.com/FasterXML/jackson-datatype-jdk8/blob/master/src/test/java/com/fasterxml/jackson/datatype/jdk8/TestConfigureAbsentsAsNulls.java
還有一個注釋 configureAbsentsAsNulls。 https://github.com/FasterXML/jackson-datatype-jdk8/blob/master/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Module.java
For compatibility with older versions
* of other "optional" values (like Guava optionals), it can be set to 'true'. The
* default is `false` for backwards compatibility.
public Jdk8Module configureAbsentsAsNulls(boolean state) {
_cfgHandleAbsentAsNull = state;
return this;
}
所以你只需要設定 configureAbsentsAsNulls(true) 來回滾你以前的狀態。
uj5u.com熱心網友回復:
我已經使用 @JsonSerialize(include = Inclusion.NON_NULL)來解決問題并且它起作用了。
uj5u.com熱心網友回復:
有三種方法可以忽略 1) 處的空欄位。欄位級別 2)。班級3)。全球范圍內
@JsonInclude(Include.NON_NULL) 私有字串用戶名;
@JsonInclude(Include.NON_NULL)
public class Book implements Comparable<Book> {
private String title;
private String author;
private int price;
public Book(String title, String author, int price) {
this.title = title;
this.author = author;
this.price = price;
}
}
// let's create a book with author as null
Book book = new Book(null, null, 42);
ObjectMapper mapper = new ObjectMapper();
// configure ObjectMapper to exclude null fields whiel serializing
mapper.setSerializationInclusion(Include.NON_NULL);
String json =mapper.writeValueAsString(cleanCode);
System.out.println(json);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/338128.html
