1. jackson的自定义序列化(null值的处理)
1.1 处理的原因
在对List类型的值进行处理时,有一部分服务是有做一些逻辑判断的,在逻辑判断不通过的时候会返回一个null值,而JSON格式的默认空值的时候为,即同样是List类型,一个是null,一个"[]"。
最简单的办法是在null值的地方全部实例化一个new ArrayList<?>(0);但是这样会修改很多地方,而且对于这些情况都要进行实例化分配内存不是那么的理想。
所以就在springMVC转json的地方做手脚。
我们都知道springMvc是使用jackson做的json序列化工具。
1.2 配置类
@Configuration
public class MyJsonConfig {
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = converter.getObjectMapper(); //ObjectMapper,即jackson序列化的主类
// 为mapper注册一个带有SerializerModifier的Factory,此modifier主要做的事情为:当序列化类型为array,list、set时,当值为空时,序列化成[]
mapper.setSerializerFactory(mapper.getSerializerFactory().withSerializerModifier(new MyBeanSerializerModifier()));
return converter;
}
}
1.3 处理对应类型为null的类
/**
* 处理数组、list、array、set类型的null值
*
* @version 1.0
*/
public class MyNullArrayJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException, JsonProcessingException {
if (value == null) {
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
}
}
/**
* 处理字符串等类型的null值
*
* @version 1.0
*/
public class MyNullJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException, JsonProcessingException {
jsonGenerator.writeString("");
}
}
/**
* 处理Integer、Long为null
*
* @version 1.0
* @date 2021/1/29/029 16:58
*/
public class MyNullNumberJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException, JsonProcessingException {
jsonGenerator.writeNull();
}
}
1.4 自定义的modifier
主要做的事情为:当序列化类型为array,list、set时,当值为空时,序列化成[],判断类型
控制将null值处理成空集合还是空字符串
public class MyBeanSerializerModifier extends BeanSerializerModifier {
/**
* 数组类型
*/
private JsonSerializer nullArrayJsonSerializer = new MyNullArrayJsonSerializer();
/**
* 字符串等类型
*/
private JsonSerializer nullJsonSerializer = new MyNullJsonSerializer();
/**
* Integer、Long类型
*/
private JsonSerializer nullNumberJsonSerializer = new MyNullNumberJsonSerializer();
/**
* 最重要的一个东西就是BeanPropertyWriter 这个类,这个类是由SerializerFactory 工厂进行实例化的
* 其作用是对bean中的每个字段进行jackson操作的封装,其中封装了字段的一些元信息
* */
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
List beanProperties) {
//循环所有的beanPropertyWriter
for (int i = 0; i < beanProperties.size(); i++) {
BeanPropertyWriter writer = (BeanPropertyWriter) beanProperties.get(i);
//判断字段的类型,如果是array,list,set则注册nullSerializer
if (isArrayType(writer)) {
//给writer注册一个自己的nullSerializer
writer.assignNullSerializer(this.nullArrayJsonSerializer);
} else if (isNumberType(writer)) {
writer.assignNullSerializer(this.nullNumberJsonSerializer);
} else {
writer.assignNullSerializer(this.nullJsonSerializer);
}
}
return beanProperties;
}
/**
* 判断是数组类型
*
* @param writer
* @return
*/
protected boolean isArrayType(BeanPropertyWriter writer) {
Class clazz = writer.getPropertyType();
return clazz.isArray() || clazz.equals(List.class) || clazz.equals(Set.class);
}
/**
* 判断是数组类型
*
* @param writer
* @return
*/
protected boolean isNumberType(BeanPropertyWriter writer) {
Class clazz = writer.getPropertyType();
return clazz.equals(Integer.class) || clazz.equals(Long.class);
}
}