一、原理:
- 通过HttpMessageConverters 可以使用xml,json或其它形式进行“封送”和“解收”(marshall and unmarshall )java对象。
- 它是通过从请求的Accept头中获取信息,从HttpMessageConverter的列表中,取得相应的Converter对象,将java对象进行“封送marshall”成为xml或json。(前提是使用了@ResponseBody或@RestController)
- 它又可以通过从请求中获取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>
- 加入新的配置类:
只需要保证容器在使用了@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;
}
}
- 相应的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
网友评论