Spring Boot HttpMessageConverter 配置

  1. 1. Spring Boot 设置消息类型转换
  2. 2. 问题小记
  3. 3. 自定义消息

Spring Boot 设置消息类型转换

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    @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);
    }
  2. 在 @Configuration 类中手动添加 Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@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 解析器
1
2
3
4
5
6
7

@Bean
public HttpMessageConverters stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(
Charset.forName("UTF-8"));
return new HttpMessageConverters(converter);
}

自定义消息

在某些特殊业务场景或者避免复杂冗余的重复,多平台请求方式不同兼容等都可通过自定义消息解析器优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/**
* @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解析

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者