转载:https://www.cnblogs.com/guoxiaoyu/p/13667961.html
最近在项目中遇到,返回对象和属性为null时,接口不返回这个字段,但在实际中即使这个字段为null也是需要返回的,也试了好多,加json注解什么的,都没效果,最后通过下面的方式实现了,特此记录一下
第一步:写配置类
@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.stream().filter(c -> c instanceof MappingJackson2HttpMessageConverter)
.map(c ->(MappingJackson2HttpMessageConverter)c)
.forEach(c->{
ObjectMapper mapper = c.getObjectMapper();
// 为mapper注册一个带有SerializerModifier的Factory,此modifier主要做的事情为:当序列化类型为array,list、set时,当值为空时,序列化成[]
mapper.setSerializerFactory(mapper.getSerializerFactory().withSerializerModifier(new MyBeanSerializerModifier()));
c.setObjectMapper(mapper);
});
}
}
第二步:编写值为null时的自定义序列化
/**
* @title: MyBeanSerializerModifier
* @Author junyu
* 旧巷里有一个穿着白衬衫笑起来如太阳般温暖我的少年。
* 记忆里有一个穿着连衣裙哭起来如孩子般讨人喜的女孩。
* 他说,哪年树弯了腰,人见了老,桃花落了白发梢,他讲的笑话她还会笑,那便是好。
* 她说,哪年国改了号,坟长了草,地府过了奈何桥,她回头看时他还在瞧,就不算糟。
* @Date: 2020/9/12 16:44
* @Version 1.0
*/
public class MyBeanSerializerModifier extends BeanSerializerModifier {
private MyNullStringJsonSerializer myNullStringJsonSerializer;
private MyNullArrayJsonSerializer MyNullArrayJsonSerializer;
private MyNullObjectJsonSerializer MyNullObjectJsonSerializer;
private MyNullJsonSerializer myNullJsonSerializer;
public MyBeanSerializerModifier(){
myNullStringJsonSerializer = new MyNullStringJsonSerializer();
MyNullArrayJsonSerializer = new MyNullArrayJsonSerializer();
MyNullObjectJsonSerializer = new MyNullObjectJsonSerializer();
myNullJsonSerializer = new MyNullJsonSerializer();
}
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyWriter> beanProperties) {
// 循环所有的beanPropertyWriter
beanProperties.forEach(writer ->{
// 判断字段的类型
if (isArrayType(writer)) {
//给writer注册一个自己的nullSerializer
writer.assignNullSerializer(MyNullArrayJsonSerializer);
} else if (isObjectType(writer)) {
writer.assignNullSerializer(MyNullObjectJsonSerializer);
} else if (isStringType(writer)) {
writer.assignNullSerializer(myNullStringJsonSerializer);
} else if (isPrimitiveType(writer)) {
writer.assignNullSerializer(myNullJsonSerializer);
}
});
return beanProperties;
}
// 判断是否是boolean类型
private boolean isPrimitiveType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return clazz.isPrimitive();
}
// 判断是否是string类型
private boolean isStringType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return clazz.equals(String.class);
}
// 判断是否是对象类型
private boolean isObjectType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return !clazz.isPrimitive() && !clazz.equals(String.class)
&& clazz.isAssignableFrom(Object.class);
}
// 判断是否是集合类型
protected boolean isArrayType(BeanPropertyWriter writer) {
Class<?> clazz = writer.getType().getRawClass();
return clazz.isArray() || clazz.equals(List.class) || clazz.equals(Set.class);
}
class MyNullJsonSerializer extends JsonSerializer<Object>{
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
if (value == null) {
jgen.writeNull();
}
}
}
class MyNullStringJsonSerializer extends JsonSerializer<Object>{
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
if (value == null) {
jgen.writeString(StringUtils.EMPTY);
}
}
}
class MyNullArrayJsonSerializer extends JsonSerializer<Object>{
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
if (value == null) {
jgen.writeStartArray();
jgen.writeEndArray();
}
}
}
class MyNullObjectJsonSerializer extends JsonSerializer<Object>{
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
if (value == null) {
jgen.writeStartObject();
jgen.writeEndObject();
}
}
}
}
这样基本配置就完事了,现在可以试试效果了,自己定义一个bean用来返回,定义一个简单的controller去接受访问就行了,博主就不进行写这两个类了。返回结果如下
这是我的项目需求需要实现的,大家可以根据的自己的需求去改写MyBeanSerializerModifier这个类。还有另一种实现方式:不继承
@Configuration
public class WebConfiguration {
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = mappingJackson2HttpMessageConverter.getObjectMapper();
mapper.setSerializerFactory(mapper.getSerializerFactory().withSerializerModifier(new MyBeanSerializerModifier()));
mappingJackson2HttpMessageConverter.setObjectMapper(mapper);
return mappingJackson2HttpMessageConverter;
}
}
这种方法也是可以设置成功的,主要是不是继承了WebMvcConfigurationSupport类,毕竟这个类有很多可以自定义的方法,用起来顺手而已。