为什么ProjectionFactory转换为空选项?



最近我更新了我的项目从Spring Boot 2.1.0到Spring Boot 2.5.6。从那以后,我看到了JSON序列化的不同之处。

为了区分以下情况(a)任意值, (b)显式null和(c)无值,我使用java.util.Optional和Jackson的@JsonInclude(NON_NULL)注释。此外,我使用Spring Data JPA的投影模式定义JSON格式如下:

public interface MyProjection {
@JsonInclude(Include.NON_NULL)
Optional<String> getMyAttribute();
}

这在Spring Boot 2.1.0中运行得很好。

tbody> <<tr>
字段值呈现的JSON
Optional.of("something"){ "myAttribute": "something" }
Optional.empty(){ "myAttribute": null }
null{}

经过几次搜索,我找到了感兴趣的测试用例。

下面是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)来回滚你之前的状态。

似乎我不能再使用java.util.Optional为我的目的。Spring开发人员扩展了ProjectingMethodInterceptor,将null值转换为所使用的包装器类型的表示(在我的例子中是Optional.empty())。

这也适用于其他包装器类型:

  • com.google.common.base.Optional
  • scala.Option
  • io.vavr.control.Option

我已经使用@JsonSerialize(include = Inclusion.NON_NULL)来解决这个问题,它起作用了。

有三种方法可以忽略空字段1)。字段级别2)。类级别3)。全局

@JsonInclude (Include.NON_NULL)private String userName;

@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);

相关内容

  • 没有找到相关文章

最新更新