HttpMessageConverter.md 7.4 KB


title: Spring Boot HttpMessageConverter 配置 date: 2018-10-09 18:33:35 tags: [Spring Boot,HttpMessageConverter]

categories: [Java,Spring]

Spring Boot 设置消息类型转换

  1. 通过实现 WebMvcConfigurer 接口 并重写 configureMessageConverters 方法

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     //创建fastJson消息转换器
     FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
     //添加多种转换类型支持
     List<MediaType> 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);
    }
    
    1. @Configuration 类中手动添加 Bean
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
    //创建fastJson消息转换器
    FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
    //添加多种转换类型支持
    List<MediaType> 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<Object> {

    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解析