一、场景分析
传统Spring应用中,往往会通过XML文件来包装一些对象的信息,我们可以使用SAXReader来解析XML文档,然后将信息读写出来。在有些场景中,需要将XML报文当参数来做请求,那么对于XML格式的请求要如何的在Controller里包装成对象,以及如何以XML的形式来返回一个对象, Sping boot能够扩展此类的特殊请求,以满足开发需要。
二、扩展实现
1. 实现原理: 消息转换器(Message Converter)
Sping boot 处理Http请求的实现采用的是Spring MVC。 在Spring MVC中含有消息转换器,主要是不同格式的请求包装转换成对象。
在SpringMVC中定义了一个HttpMessageConverter 接口,对消息类型的判断以及对读写的判断等操作:
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException,HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessag e) throws IOException, HttpMessageNotWritableException;
}
HTTP请求的Content-Type有种不同的格式定义,如果要支持Xml格式的消息转换,就必须要使用不同格式的消息转换器。
SpringMVC有一套默认的JACKSON转换器 : MappingJackson2XmlHttpMessageConverter。
2. 实现步骤:
传统应用中可以通过增加如下配置: 继承 WebMvcConfigurerAdapter类来定义消息转换器
@Configuration
public class MessageConverterConfig1 extends WebMvcConfigurerAdapter{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters){
Jackson2ObjectMapperBuilder builder =Jackson2ObjectMapperBuilder.xml();
builder.indentOutput(true);
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.build())) ;
}
}
在springboot应用中,只需要添加一个依赖: jackson-dataformat-xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
然后定义映射的XML与对象的关系:
@Data
@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName="User")
public class User{
@JacksonXmlProperty(localName="name")
private String name;
@JacksonXmlProperty(localName="age")
private Integer age;
}
对应的xml报文为:
<User>
<name>aaaa</name>
<age>10</age>
</User>
controller: 同时定义类型为:
consumes= MediaType.APPLICATION_XML_VALUE
produces=MediaType.APPLICATION_XML_VALUE
@Controller
public class UserController {
@PostMapping(value = "/user",consumes=MediaType.APPLICATION_XML_VALUE,produces=MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public User create(@RequestBody User user){
user.setName("name:"+user.getName());
user.setAge(user.getAge()+100);
return user;
}
}