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 的作用以及其他配置在我的另一篇博客做了说明