一、場景分析
傳統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;
}
}