jackson并没有提供分类别处理null,jackson的核心类ObjectMapper
暴露的NullSerializer
无法针对不同类型设定不同的默认值,所幸jackson有完善的扩展机制。BeanSerializerModifier
的changeProperties()
方法提供了细粒度控制每个Field的序列化行为的可能,代码如下。
public enum SerializerFeature {
WriteNullListAsEmpty,
WriteNullStringAsEmpty,
WriteNullNumberAsZero,
WriteNullBooleanAsFalse;
public final int mask;
SerializerFeature() {
mask = (1 << ordinal());
}
}
final public static class FastJsonSerializerFeatureCompatibleForJackson extends BeanSerializerModifier {
final private JsonSerializer<Object> nullBooleanJsonSerializer;
final private JsonSerializer<Object> nullNumberJsonSerializer;
final private JsonSerializer<Object> nullListJsonSerializer;
final private JsonSerializer<Object> nullStringJsonSerializer;
FastJsonSerializerFeatureCompatibleForJackson(SerializerFeature... features) {
int config = 0;
for (SerializerFeature feature : features) {
config |= ;
}
nullBooleanJsonSerializer = (config & ) != 0 ? new NullBooleanSerializer() : null;
nullNumberJsonSerializer = (config & ) != 0 ? new NullNumberSerializer() : null;
nullListJsonSerializer = (config & ) != 0 ? new NullListJsonSerializer() : null;
nullStringJsonSerializer = (config & ) != 0 ? new NullStringSerializer() : null;
}
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
for (BeanPropertyWriter writer : beanProperties) {
final JavaType javaType = ();
final Class<?> rawClass = ();
if (() || ()) {
(nullListJsonSerializer);
} else if ((rawClass) && ().startsWith("")) {
(nullNumberJsonSerializer);
} else if ((rawClass)) {
(nullBooleanJsonSerializer);
} else if ((rawClass)) {
(nullStringJsonSerializer);
}
}
return beanProperties;
}
private static class NullListJsonSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
();
();
}
}
private static class NullNumberSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
(0);
}
}
private static class NullBooleanSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
(false);
}
}
private static class NullStringSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
("");
}
}
}
最后把该
Modifier
注入到
ObjectMapper
中。
(().withSerializerModifier(new FastJsonSerializerFeatureCompatibleForJackson(features)));
反序列化时忽略不存在的字段
在标准Json规范中,如果尝试反序列化一个Json字符串为指定的POJO,而且字符串中有一个Field在POJO中不存在,应该抛出错误。对于这种情况,fastjson默认是跳过,jackson默认是中止。
(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
重新设置SpringMVC的HttpMessageConvertor
<bean class=".MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="">
<constructor-arg>
<util:list>
<value>WriteNullListAsEmpty</value>
<value>WriteNullStringAsEmpty</value>
<value>WriteNullNumberAsZero</value>
<value>WriteNullBooleanAsFalse</value>
</util:list>
</constructor-arg>
</bean>
</property>
</bean>
由于需要编程式的设置全局配置,扩展
FactoryBean
(
CustomObjectMapperFactoryBean
)生成自定义的
ObjectMapper
来替代
MappingJackson2HttpMessageConverter
中默认
ObjectMapper
。
final public static class CustomObjectMapperFactoryBean implements FactoryBean<ObjectMapper> {
SerializerFeature[] features;
public CustomObjectMapperFactoryBean(SerializerFeature[] features) {
= features;
}
@Override
public ObjectMapper getObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
(().withSerializerModifier(new FastJsonSerializerFeatureCompatibleForJackson(features))).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}
@Override
public Class<?> getObjectType() {
return ;
}
@Override
public boolean isSingleton() {
return false;
}
}