SpringBoot在controller方法使用@ResponseBody将输出解析为json格式数据,它默认使用jackson来序列化json,实现类是MappingJackson2HttpMessageConverter.java,下面用fastjson来自定义输出json。
导包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
接口
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/connection", produces = "application/customjson")
public APIResult testConnection() {
User user = new User();
user.setAge("25");
user.setName(null);
APIResult<User> result = new APIResult<>();
result.setCode(null);
result.setData(user);
result.setMsg(null);
return result;
}
}
注意它的produces ,是我自定义的"application/customjson",自定义的消息解析器会处理这种类型的返回
消息解析器
/**
* 自定义消息转换器,继承FastJson消息转换器
*/
public class CustomMessageConverter extends FastJsonHttpMessageConverter {
/**
* 重写write方法,响应最后将MediaType改为application/json返回,
* 否则自定义请求头类型前端是无法识别的
*/
@Override
public void write(Object o, Type type, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//传入的MediaType是application/customjson,改为application/json
super.write(o, MediaType.APPLICATION_JSON, outputMessage);
}
}
本来用fastjson的FastJsonHttpMessageConverter即可 ,这里继承它只是为了重写它的write方法,将media-type改为"application/json",保证处理完成后以“content-type=application/json"返回给前端,因为浏览器无法解析我们自定义的application/customjson
消息解析器添加到spring
@Configuration
public class MVConfig implements WebMvcConfigurer {
/**
* 添加自定义消息内容转换器
* 处理自定义MediaType,produces = "application/customjson"的响应报文
* @param converters
*/
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fjhmc = new CustomMessageConverter();
List<MediaType> mediaTypeList = new ArrayList<>();
//处理application/customjson类型的消息
mediaTypeList.add(MediaType.parseMediaType("application/customjson"));
fjhmc.setSupportedMediaTypes(mediaTypeList);
//2、添加fastjson的配置信息
FastJsonConfig fastJsonConfig = new FastJsonConfig();
SerializerFeature[] serializerFeatures = new SerializerFeature[]{
// 是否输出为null的字段,若为null 则显示该字段
// SerializerFeature.WriteMapNullValue,
// 数值字段如果为null,则输出为0
SerializerFeature.WriteNullNumberAsZero,
// List字段如果为null,输出为[],而非null
SerializerFeature.WriteNullListAsEmpty,
// 字符类型字段如果为null,输出为"",而非null
SerializerFeature.WriteNullStringAsEmpty,
// Boolean字段如果为null,输出为false,而非null
SerializerFeature.WriteNullBooleanAsFalse,
// 输出map中的null字段
SerializerFeature.WriteMapNullValue,
// Date的日期转换器
SerializerFeature.WriteDateUseDateFormat,
// 循环引用
SerializerFeature.DisableCircularReferenceDetect,
};
fastJsonConfig.setSerializerFeatures(serializerFeatures);
fastJsonConfig.setCharset(Charset.forName("UTF-8"));
fjhmc.setFastJsonConfig(fastJsonConfig);
converters.add(fjhmc);
}
}
这里将自定义的解析器加入到解析器列表(spring本身有各种格式的解析器),并指定它处理application/customjson类型的输出,SerializerFeature提供了很多自定义处理方式,按需使用。
需要注意的是,如果自定义解析器处理application/json是不生效的,因为前文提到的springboot自己的解析器MappingJackson2HttpMessageConverter便是用来处理application/json的,我们的自定义解析器只是添加到解析器列表,而并不是替代原先的,程序还是会调用springboot的json解析器,所以这里自定义application/customjson。
测试
浏览器地址栏调用:http://localhost:9527/jason/test/connection
返回:
{"code":0,"data":{"age":"25","name":""},"msg":""}
Integer的null输出为0,String的null输出为""。目的达到
另外,关于代码中WebMvcConfigurer 的作用以及其他配置在我的另一篇博客做了说明