--- title: Spring Boot HttpMessageConverter 配置 date: 2018-10-09 18:33:35 tags: [Spring Boot,HttpMessageConverter] categories: [Java,Spring] --- #### Spring Boot 设置消息类型转换 1. 通过实现 WebMvcConfigurer 接口 并重写 configureMessageConverters 方法 ```java @Override public void configureMessageConverters(List> converters) { //创建fastJson消息转换器 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //添加多种转换类型支持 List supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); supportedMediaTypes.add(MediaType.APPLICATION_PDF); supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); supportedMediaTypes.add(MediaType.APPLICATION_XML); supportedMediaTypes.add(MediaType.IMAGE_GIF); supportedMediaTypes.add(MediaType.IMAGE_JPEG); supportedMediaTypes.add(MediaType.IMAGE_PNG); supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); supportedMediaTypes.add(MediaType.TEXT_HTML); supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); supportedMediaTypes.add(MediaType.TEXT_PLAIN); supportedMediaTypes.add(MediaType.TEXT_XML); fastConverter.setSupportedMediaTypes(supportedMediaTypes); //创建配置类 FastJsonConfig fastJsonConfig = new FastJsonConfig(); //设置默认时间转换格式 JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; //修改配置返回内容的过滤 //WriteNullListAsEmpty :List字段如果为null,输出为[],而非null //WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null //DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环) //WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null //WriteMapNullValue:是否输出值为null的字段,默认为false //WriteDateUseDateFormat 使用自定义时间格式 fastJsonConfig.setSerializerFeatures( SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat ); fastConverter.setFastJsonConfig(fastJsonConfig); //将fastjson添加到视图消息转换器列表内 // converters.add(0, fastConverter); 可提高优先级 converters.add(fastConverter); } ``` 2. 在 @Configuration 类中手动添加 Bean ```java @Bean public HttpMessageConverters fastJsonHttpMessageConverters() { //创建fastJson消息转换器 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //添加多种转换类型支持 List supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); supportedMediaTypes.add(MediaType.APPLICATION_PDF); supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); supportedMediaTypes.add(MediaType.APPLICATION_XML); supportedMediaTypes.add(MediaType.IMAGE_GIF); supportedMediaTypes.add(MediaType.IMAGE_JPEG); supportedMediaTypes.add(MediaType.IMAGE_PNG); supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); supportedMediaTypes.add(MediaType.TEXT_HTML); supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); supportedMediaTypes.add(MediaType.TEXT_PLAIN); supportedMediaTypes.add(MediaType.TEXT_XML); fastConverter.setSupportedMediaTypes(supportedMediaTypes); //创建配置类 FastJsonConfig fastJsonConfig = new FastJsonConfig(); //设置默认时间转换格式 JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; //修改配置返回内容的过滤 //WriteNullListAsEmpty :List字段如果为null,输出为[],而非null //WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null //DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环) //WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null //WriteMapNullValue:是否输出值为null的字段,默认为false //WriteDateUseDateFormat 使用自定义时间格式 fastJsonConfig.setSerializerFeatures( SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat ); fastConverter.setFastJsonConfig(fastJsonConfig); return new HttpMessageConverters(fastConverter); } ``` #### 问题小记 - jackson-dataformat-xml 依赖会影响解析器的加载,应设置默认加载类型或调整顺序 - converters 解析有顺。如果使用第一种方法,可能使用默认使用 MappingJackson2HttpMessageConverter 导致新添加的解析器不生效,即使用第二种方法 - 若出现返回的json数据中包含/ 转移 等字符,可在当前加载器前添加 StringHttpMessageConverter 解析器 ``` @Bean public HttpMessageConverters stringHttpMessageConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter( Charset.forName("UTF-8")); return new HttpMessageConverters(converter); } ``` #### 自定义消息 > 在某些特殊业务场景或者避免复杂冗余的重复,多平台请求方式不同兼容等都可通过自定义消息解析器优化 ``` /** * @author : wangzhiyong * @date : 2019/1/25 15:30 * description : 系统自定义消息转换器 */ public class CustomHttpMessageConverter extends AbstractHttpMessageConverter { CustomHttpMessageConverter() { // 自定义请求类型解析 super(new MediaType("application", "dzdy", Charset.forName("UTF-8"))); } @Override protected boolean supports(Class clazz) { // 用于处理某特殊类或者true 全部类 return true; } @Override protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { // todo 特殊的加密或字符串解析 InputStream inputStream = inputMessage.getBody(); StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, StandardCharsets.UTF_8.name()); String str = writer.toString(); return JSONObject.parseObject(str, clazz); } @Override protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { // todo 特殊的解密或字符串拼接 OutputStream outputStream = outputMessage.getBody(); IOUtils.write(JSONObject.toJSONString(o), outputStream, StandardCharsets.UTF_8.name()); outputStream.flush(); outputStream.close(); } } ``` eg. 请求对象需添加 @RequestBody 定义走mvc解析