在第一次序列化后配置 ObjecMapper 空序列化没有效果
Configuring ObjecMapper null serialization after first serialization does not have effect
在使用 ObjectMapper
进行一些实验时偶然发现了这种行为。请参阅下面的 Junit5 测试用例以及那些在评论中为我打印的内容。
class TestIt {
private ObjectMapper om = new ObjectMapper();
private TestClass testClass = new TestClass();
@Getter @Setter
public class TestClass {
private final String value = LocalDate.now().toString();
private String valueLeftNull;
}
@Test
void defaultMapping() throws JsonProcessingException {
System.out.println(om.writeValueAsString(testClass));
// {"value":"2020-11-02","valueLeftNull":null}
}
@Test
void nonNull() throws JsonProcessingException {
om.setSerializationInclusion(Include.NON_NULL);
System.out.println(om.writeValueAsString(testClass));
// {"value":"2020-11-02"}
}
@Test
void both() throws JsonProcessingException {
System.out.println(om.writeValueAsString(testClass));
om.setSerializationInclusion(Include.NON_NULL);
System.out.println(om.writeValueAsString(testClass));
System.out.println(om.writeValueAsString(new TestClass()));
// {"value":"2020-11-02","valueLeftNull":null}
// {"value":"2020-11-02","valueLeftNull":null}
// {"value":"2020-11-02","valueLeftNull":null}
}
}
最后一个both()
是我想知道的。 ObjectMapper
第一次序列化后忽略包含指令是正常功能吗?
默认情况下 Jackson
为每个 POJO
class 创建 BeanSerializer 个实例。它是在需要时按需创建的,并且 已缓存 。所以它的配置取决于 ObjectMapper
的当前状态,如果你改变 ObjectMapper
你需要清除缓存:
((DefaultSerializerProvider) om.getSerializerProvider()).flushCachedSerializers();
强制ObjectMapper
创建BeanSerializer
的新实例。
查看 BeanSerializerFactory 的文档:
...
Finally, since all caching is handled by the serializer provider
(not factory) and there is no configurability, this factory is
stateless. This means that a global singleton instance can be used.
Method that can be used to determine how many serializers this
provider is caching currently (if it does caching: default
implementation does) Exact count depends on what kind of serializers
get cached; default implementation caches all serializers, including
ones that are eagerly constructed (for optimal access speed)
最好的解决方案可能是创建 ObjectMapper
:
的两个实例
class TestIt {
private JsonMapper nonNullMapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.build();
private JsonMapper defaultMapper = JsonMapper.builder().build();
private TestClass testClass = new TestClass();
@Getter
@Setter
public static class TestClass {
private final String value = LocalDate.now().toString();
private String valueLeftNull;
}
void defaultMapping() throws JsonProcessingException {
System.out.println(defaultMapper.writeValueAsString(testClass));
}
void nonNull() throws JsonProcessingException {
System.out.println(nonNullMapper.writeValueAsString(testClass));
}
void both() throws JsonProcessingException {
System.out.println(defaultMapper.writeValueAsString(testClass));
System.out.println(nonNullMapper.writeValueAsString(testClass));
System.out.println(nonNullMapper.writeValueAsString(new TestClass()));
}
}
在使用 ObjectMapper
进行一些实验时偶然发现了这种行为。请参阅下面的 Junit5 测试用例以及那些在评论中为我打印的内容。
class TestIt {
private ObjectMapper om = new ObjectMapper();
private TestClass testClass = new TestClass();
@Getter @Setter
public class TestClass {
private final String value = LocalDate.now().toString();
private String valueLeftNull;
}
@Test
void defaultMapping() throws JsonProcessingException {
System.out.println(om.writeValueAsString(testClass));
// {"value":"2020-11-02","valueLeftNull":null}
}
@Test
void nonNull() throws JsonProcessingException {
om.setSerializationInclusion(Include.NON_NULL);
System.out.println(om.writeValueAsString(testClass));
// {"value":"2020-11-02"}
}
@Test
void both() throws JsonProcessingException {
System.out.println(om.writeValueAsString(testClass));
om.setSerializationInclusion(Include.NON_NULL);
System.out.println(om.writeValueAsString(testClass));
System.out.println(om.writeValueAsString(new TestClass()));
// {"value":"2020-11-02","valueLeftNull":null}
// {"value":"2020-11-02","valueLeftNull":null}
// {"value":"2020-11-02","valueLeftNull":null}
}
}
最后一个both()
是我想知道的。 ObjectMapper
第一次序列化后忽略包含指令是正常功能吗?
默认情况下 Jackson
为每个 POJO
class 创建 BeanSerializer 个实例。它是在需要时按需创建的,并且 已缓存 。所以它的配置取决于 ObjectMapper
的当前状态,如果你改变 ObjectMapper
你需要清除缓存:
((DefaultSerializerProvider) om.getSerializerProvider()).flushCachedSerializers();
强制ObjectMapper
创建BeanSerializer
的新实例。
查看 BeanSerializerFactory 的文档:
...
Finally, since all caching is handled by the serializer provider (not factory) and there is no configurability, this factory is stateless. This means that a global singleton instance can be used.
Method that can be used to determine how many serializers this provider is caching currently (if it does caching: default implementation does) Exact count depends on what kind of serializers get cached; default implementation caches all serializers, including ones that are eagerly constructed (for optimal access speed)
最好的解决方案可能是创建 ObjectMapper
:
class TestIt {
private JsonMapper nonNullMapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.build();
private JsonMapper defaultMapper = JsonMapper.builder().build();
private TestClass testClass = new TestClass();
@Getter
@Setter
public static class TestClass {
private final String value = LocalDate.now().toString();
private String valueLeftNull;
}
void defaultMapping() throws JsonProcessingException {
System.out.println(defaultMapper.writeValueAsString(testClass));
}
void nonNull() throws JsonProcessingException {
System.out.println(nonNullMapper.writeValueAsString(testClass));
}
void both() throws JsonProcessingException {
System.out.println(defaultMapper.writeValueAsString(testClass));
System.out.println(nonNullMapper.writeValueAsString(testClass));
System.out.println(nonNullMapper.writeValueAsString(new TestClass()));
}
}