Spring boot与HttpMessageConverter



默认的HttpMessageConverter

在构建RESTful服务时, 我们常常会把一个对象直接转换成json对象, 就像下面这样:

@RestController
public class HomeController {
    @RequestMapping("/")
    Map<String, Object> home() {
        Map<String, Object> map = Maps.newHashMap();
        map.put("name", "中文");
        map.put("age", 18);
        return map;
    }
}

Spring提供了多种HttpMessageConverter让我们对结果进行转换, 像上面那样, 把对象转换成json格式输出, Spring boot默认使用MappingJackson2HttpMessageConverter进行转换. 如果我们想要使用另一个工具进行json转换, 或者想添加自己的HttpMessageConverter, Spring boot提供了多种不通的方式来实现.

自定义HttpMessageConverter

我们以GsonHttpMessageConverter为例, 除了主配置类之外, 我们添加另一个配置类, 从这个类中添加自己的Converter

方式一

直接添加一个Bean, 它将添加到Converter列表的最前面

  • 优点: 简单, 无需继承其他类
  • 缺点: 不容易直观地看出, 有一个Converter列表

代码如下:


@Configuration
public class WebMvcConfig {
    @Bean
    public GsonHttpMessageConverter gsonHttpMessageConverter() {
        Gson gson = new GsonBuilder().serializeNulls()    // null 也序列化
                .setDateFormat("yyyy-MM-dd HH:mm:ss")     // 时间转化为特定格式 yyyy-MM-dd HH:mm:ss
                .create();
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        converter.setGson(gson);
        return converter;
    }
}

方式二

继承WebMvcConfigurerAdapter, 覆盖configureMessageConverters方法

  • 优点: 直观看到有个List, 断点调试会发现, 这是向列表中添加的第一个Converter
  • 缺点: 要是有多个配置也以同样的方式添加了其他Converter, 就无法保证以固定的顺序添加到列表中了

代码如下:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Gson gson = new GsonBuilder().serializeNulls()    // null 也序列化
                .setDateFormat("yyyy-MM-dd HH:mm:ss")     // 时间转化为特定格式 yyyy-MM-dd HH:mm:ss
                .create();
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        converter.setGson(gson);
        converters.add(converter);
    }
}

方式三

继承WebMvcConfigurerAdapter, 覆盖extendMessageConverters方法

  • 优点: 这个方法在其他Converter加入列表之后执行, 可以进行精确控制, 如顺序等
  • 缺点: 同样有可能, 别的配置里也以相同方式重写了这个方法

代码如下:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.clear();  // 把其他 converter 清除掉
        Gson gson = new GsonBuilder().serializeNulls()    // null 也序列化
                .setDateFormat("yyyy-MM-dd HH:mm:ss")     // 时间转化为特定格式 yyyy-MM-dd HH:mm:ss
                .create();
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        converter.setGson(gson);
        converters.add(converter);
    }
}