美文网首页
HttpMessageConverters 使用详解

HttpMessageConverters 使用详解

作者: JohnYuCN | 来源:发表于2021-07-08 19:12 被阅读0次

一、原理:

  1. 通过HttpMessageConverters 可以使用xml,json或其它形式进行“封送”和“解收”(marshall and unmarshall )java对象。
  2. 它是通过从请求的Accept头中获取信息,从HttpMessageConverter的列表中,取得相应的Converter对象,将java对象进行“封送marshall”成为xml或json。(前提是使用了@ResponseBody或@RestController)
  3. 它又可以通过从请求中获取Content-Type头信息,从从HttpMessageConverter的列表中,取得相应的Converter对象,将请求体进行“解收unmarshall”,从而转化成为java对象(前提是使用了@RequestBody对参数进行了注解)。

二、预置的Converter:

ByteArrayHttpMessageConverter – converts byte arrays
StringHttpMessageConverter – converts Strings
ResourceHttpMessageConverter – converts org.springframework.core.io.Resource for any type of octet stream
SourceHttpMessageConverter – converts javax.xml.transform.Source
FormHttpMessageConverter – converts form data to/from a MultiValueMap<String, String>.
Jaxb2RootElementHttpMessageConverter – converts Java objects to/from XML (added only if JAXB2 is present on the classpath)
MappingJackson2HttpMessageConverter – converts JSON (added only if Jackson 2 is present on the classpath)
MappingJacksonHttpMessageConverter – converts JSON (added only if Jackson is present on the classpath)
AtomFeedHttpMessageConverter – converts Atom feeds (added only if Rome is present on the classpath)
RssChannelHttpMessageConverter – converts RSS feeds (added only if Rome is present on the classpath)

三、案例:

场景分析:针对 Accept和Content-Type 为application/xml的形式的请求,要完成java bean和 xml形式的转化。

1.思路一:

我们可以使用Jaxb2RootElementHttpMessageConverter ,此时只需要将JAXB2库加入到依赖中即可。

开发过程如下:
  • 在pom.xml中按要求加入JAXB2的运行库
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.2</version>
        </dependency>
  • 对java bean 进行注解(这是使用Jaxb2RootElementHttpMessageConverter的最大弱点):
@XmlRootElement
public class Book {
...

2. 思路二:

我们也可以添加一个新的MarshallingHttpMessageConverter,它中以组合Marshaller和Unmarshaller,只需要有实现了Marshaller, Unmarshaller 接口的对象来完成即可;本案例使用了org.springframework.oxm.xstream.XStreamMarshaller

开发过程如下:
  • pom.xml中加入相应的Marshaller依赖库:
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.oxm</artifactId>
            <version>3.2.2.RELEASE</version>
        </dependency>
  1. 加入新的配置类:
    只需要保证容器在使用了@EnableWebMvc容器,并可以扫描到以下类的前提下,即可完成工作。
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.xstream.XStreamMarshaller;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    //向系统预置的Converter列表中,加入新的Converter
    //此时系统中原先处理application/xml的Jaxb2RootElementHttpMessageConverter 将会被覆盖!!
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        //加入"通用的converter"
        messageConverters.add(createXmlHttpMessageConverter());
        //以下这行代码在Spring5中是默认的配置,只是为了演示加入"专用converter"的方法
        messageConverters.add(new MappingJackson2HttpMessageConverter());
    }

    private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
        //这个是"通用Converter"可以灵活的配置相应的Marshaller和Unmarshaller
        MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
        //XStreamMarshaller可以处理Accept:application/xml类型的请求
        XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
        //组合的过程,这样以后可以高度灵活的配置不同的Marshaller
        xmlConverter.setMarshaller(xstreamMarshaller);
        xmlConverter.setUnmarshaller(xstreamMarshaller);

        return xmlConverter;
    }
}
  1. 相应的controller:
    //此时根据accept头的值是:application/json或application/xml的不同情况,即可以返回相应的封装数据
    @RequestMapping(value = "/test1")
    public @ResponseBody Payment test1(){
        Payment payment = new Payment();
        payment.setSerial("xyz");
        payment.setId(100L);
        return  payment;
    }

---参考:https://www.baeldung.com/spring-httpmessageconverter-rest

相关文章

网友评论

      本文标题:HttpMessageConverters 使用详解

      本文链接:https://www.haomeiwen.com/subject/lnvtpltx.html