Spring Boot 2.x实战39 - Spring Web MVC 11 - Web MVC配置(HttpMessageConverter)

3.5 HttpMessageConverter

在Spring MVC中请求(@RequestBodyRequestEntity等)和返回(@ResponsebodyResponseEntity等)都是通过HttpMessageConverter来实现数据转换的。

外部的请求数据通过HttpMessageConverter转换成Java对象,而Java对象又通过HttpMessageConverter转换成外部数据到返回中。在我们前面的例子中,web请求体中的Json数据通过MappingJackson2HttpMessageConverter转换成Java对象,而Java对象也通过MappingJackson2HttpMessageConverter转换成Json到返回体中。

HttpMessageConverter会根据请求或返回的内容类型(Content-Typeapplication/json)来选择对应的HttpMessageConverter对数据进行转换。

Spring MVC为我们自动注册了下列的HttpMessageConverter

  • ByteArrayHttpMessageConverter:二进制数组转换

  • StringHttpMessageConverter:字符串转换,支持的媒体类型:

  • ResourceHttpMessageConverterorg.springframework.core.io.Resource类型转换

  • SourceHttpMessageConverterjavax.xml.transform.Source类型准换

  • 各种Json库的HttpMessageConverter

    • MappingJackson2HttpMessageConverter:当jackson-databind jar包在类路径时注册,当前请求体和返回体都是用它来做数据转换的
    • MappingJackson2XmlHttpMessageConverter:当jackson-dataformat-xml jar包在类路径时注册
    • Jaxb2RootElementHttpMessageConverter:当jaxb-api jar包在类路径时注册
    • GsonHttpMessageConverter:当gson jar包在类路径时注册
    • JsonbHttpMessageConverter:当javax.json.bind-api jar包在类路径时注册

我们也定义一个HttpMessageConverter来演示它的功能。我们首先定义一个我们专门用来演示数据转换的类:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class AnotherPerson {
    private Long id;
    private String name;
    private Integer age;
}

继承AbstractHttpMessageConverter(实现了HttpMessageConverter接口)抽象类来定制:

public class AnotherPersonHttpMessageConverter extends AbstractHttpMessageConverter<AnotherPerson> {

    public AnotherPersonHttpMessageConverter() {
        super(new MediaType("application","another-person", Charset.defaultCharset()));//1
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return AnotherPerson.class.isAssignableFrom(clazz); //2
    }

    @Override
    protected AnotherPerson readInternal(Class<? extends AnotherPerson> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        String body = StreamUtils.copyToString(inputMessage.getBody(), Charset.defaultCharset());
        String[] personStr = body.split("-");
        return new AnotherPerson(Long.valueOf(personStr[0]), personStr[1], Integer.valueOf(personStr[2])); //3
    }

    @Override
    protected void writeInternal(AnotherPerson anotherPerson, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        String out = "Hello:" + anotherPerson.getId() + "-" +
                anotherPerson.getName() + "-" +
                anotherPerson.getAge();
        StreamUtils.copy(out, Charset.defaultCharset(), outputMessage.getBody()); //4
    }
}
  1. 构造器中自定义我们自己的媒体类型application/another-person
  2. 当前HttpMessageConverter支持转换的类型是AnotherPerson类;
  3. 将请求体内的字符串6-foo-28转换成AnotherPerson对象;
  4. AnotherPerson对象转换成对应的字符串形式。

注册HttpMessageConverter的方式很多:

  • 直接定义Bean:

    @Bean
    HttpMessageConverter anotherPersonHttpMessageConverter(){
        return new AnotherPersonHttpMessageConverter();
    }
    
  • 定义HttpMessageConverters的Bean,这是Spring Boot为我们专门提供的,推荐使用

    @Bean
    HttpMessageConverters httpMessageConverters(){
        return new HttpMessageConverters(new AnotherPersonHttpMessageConverter());
    }
    
  • 重载WebMvcConfigurer的方法configureMessageConverters

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new AnotherPersonHttpMessageConverter());
    }
    

我们使用前两种注册HttpMessageConverter方式时,控制器:

@GetMapping("/converter")
public AnotherPerson converter(@RequestBody AnotherPerson person){
    return person;
}

使用第三种注册方式时,因Spring MVC默认使用MappingJackson2HttpMessageConverter来对请求体和返回体进行处理,我们需指定返回体的媒体类型:

@GetMapping(value = "/converter", produces = {"application/another-person"})
public AnotherPerson converter(@RequestBody AnotherPerson person){
    return person;
}

我们用Postman请求时候,要将请求头的Content-Type设置为application/another-person

Spring Boot 2.x实战39 - Spring Web MVC 11 - Web MVC配置(HttpMessageConverter)_第1张图片

我们请求的格式也是用“-”隔开:
Spring Boot 2.x实战39 - Spring Web MVC 11 - Web MVC配置(HttpMessageConverter)_第2张图片

新书推荐:

我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html
在这里插入图片描述

主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。

你可能感兴趣的:(Spring,Boot2.x实战全集,Spring,Boot2.x实战,-,Spring,MVC,spring,boot,mvc,config,Converter)