Spring Boot中擴展XML請求與響應(yīng)的支持詳解
前言
在之前的所有Spring Boot教程中,我們都只提到和用到了針對HTML和JSON格式的請求與響應(yīng)處理。那么對于XML格式的請求要如何快速的在Controller中包裝成對象,以及如何以XML的格式返回一個對象呢?
什么是xml文件格式
我們要給對方傳輸一段數(shù)據(jù),數(shù)據(jù)內(nèi)容是“too young,too simple,sometimes naive”,要將這段話按照屬性拆分為三個數(shù)據(jù)的話,就是,年齡too young,閱歷too simple,結(jié)果sometimes naive。我們都知道程序不像人,可以體會字面意思,并自動拆分出數(shù)據(jù),因此,我們需要幫助程序做拆分,因此出現(xiàn)了各種各樣的數(shù)據(jù)格式以及拆分方式。比如,可以是這樣的數(shù)據(jù)為“too young,too simple,sometimes naive”然后按照逗號拆分,第一部分為年齡,第二部分為閱歷,第三部分為結(jié)果。也可以是這樣的數(shù)據(jù)為“too_young* too_simple*sometimes_naive”從數(shù)據(jù)開頭開始截取前面十一個字符,去掉號并把下劃線替換為空格作為第一部分,再截取接下來的十一個字符同樣去掉并替換下劃線為空格作為第二部分,最后把剩下的字符同樣去號體會空格作為第三部分。這兩種方式都可以用來容納數(shù)據(jù)并能夠被解析,但是不直觀,通用性也不好,而且如果出現(xiàn)超過限定字數(shù)的字符串就容納不了,也可能出現(xiàn)數(shù)據(jù)本身就下劃線字符導(dǎo)致需要做轉(zhuǎn)義?;谶@種情況,出現(xiàn)了xml這種數(shù)據(jù)格式, 上面的數(shù)據(jù)用XML表示的話可以是這樣
實現(xiàn)原理:消息轉(zhuǎn)換器(Message Converter)
在擴展上述問題之前,我們先要知道Spring Boot中處理HTTP請求的實現(xiàn)是采用的Spring MVC。而在Spring MVC中有一個消息轉(zhuǎn)換器這個概念,它主要負責(zé)處理各種不同格式的請求數(shù)據(jù)進行處理,并包轉(zhuǎn)換成對象,以提供更好的編程體驗。
在Spring MVC中定義了HttpMessageConverter接口,抽象了消息轉(zhuǎn)換器對類型的判斷、對讀寫的判斷與操作,具體可見如下定義:
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 outputMessage) throws IOException, HttpMessageNotWritableException;
}
眾所周知,HTTP請求的Content-Type有各種不同格式定義,如果要支持Xml格式的消息轉(zhuǎn)換,就必須要使用對應(yīng)的轉(zhuǎn)換器。Spring MVC中默認已經(jīng)有一套采用Jackson實現(xiàn)的轉(zhuǎn)換器MappingJackson2XmlHttpMessageConverter。
擴展實現(xiàn)
第一步:引入Xml消息轉(zhuǎn)換器
在傳統(tǒng)Spring應(yīng)用中,我們可以通過如下配置加入對Xml格式數(shù)據(jù)的消息轉(zhuǎn)換實現(xiàn):
@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()));
}
}
在Spring Boot應(yīng)用不用像上面這么麻煩,只需要加入jackson-dataformat-xml依賴,Spring Boot就會自動引入MappingJackson2XmlHttpMessageConverter的實現(xiàn):
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
同時,為了配置Xml數(shù)據(jù)與維護對象屬性的關(guān)系所要使用的注解也在上述依賴中,所以這個依賴也是必須的。
第二步:定義對象與Xml的關(guān)系
做好了基礎(chǔ)擴展之后,下面就可以定義Xml內(nèi)容對應(yīng)的Java對象了,比如:
@Data
@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "User")
public class User {
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlProperty(localName = "age")
private Integer age;
}
其中:@Data、@NoArgsConstructor、@AllArgsConstructor是lombok簡化代碼的注解,主要用于生成get、set以及構(gòu)造函數(shù)。@JacksonXmlRootElement、@JacksonXmlProperty注解是用來維護對象屬性在xml中的對應(yīng)關(guān)系。
上述配置的User對象,其可以映射的Xml樣例如下(后續(xù)可以使用上述xml來請求接口):
<User> <name>aaaa</name> <age>10</age> </User>
第三步:創(chuàng)建接收xml請求的接口
完成了要轉(zhuǎn)換的對象之后,可以編寫一個接口來接收xml并返回xml,比如:
@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("didispace.com : " + user.getName());
user.setAge(user.getAge() + 100);
return user;
}
}
最后,啟動Spring Boot應(yīng)用,通過POSTMAN等請求工具,嘗試一下這個接口,可以看到請求Xml,并且返回了經(jīng)過處理后的Xml內(nèi)容。
案例代碼
可以通過下面兩個倉庫中查閱chapter3-1-8目錄:
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
java數(shù)據(jù)結(jié)構(gòu)ArrayList詳解
本文詳細講解了java數(shù)據(jù)結(jié)構(gòu)ArrayList的用法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12
java實現(xiàn)動態(tài)時鐘并設(shè)置鬧鐘功能
這篇文章主要為大家詳細介紹了java實現(xiàn)動態(tài)時鐘并設(shè)置鬧鐘功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01
Java中LinkedList詳解和使用示例_動力節(jié)點Java學(xué)院整理
LinkedList 是一個繼承于AbstractSequentialList的雙向鏈表。它也可以被當(dāng)作堆棧、隊列或雙端隊列進行操作。接下來通過示例代碼給大家詳細介紹java中l(wèi)inkedlist的使用,需要的朋友參考下吧2017-05-05
SpringCloud feign服務(wù)熔斷下的異常處理操作
這篇文章主要介紹了SpringCloud feign服務(wù)熔斷下的異常處理操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Spring?Boot?集成Elasticsearch模塊實現(xiàn)簡單查詢功能
本文講解了Spring?Boot集成Elasticsearch采用的是ES模板的方式實現(xiàn)基礎(chǔ)查詢,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2022-06-06
springboot使用redis緩存亂碼(key或者value亂碼)的解決
在通過springboot緩存數(shù)據(jù)的時候,發(fā)現(xiàn)key是一堆很不友好的東西,本文主要介紹了springboot使用redis緩存亂碼(key或者value亂碼)的解決,感興趣的可以了解一下2023-11-11
SpringBoot?AnnotationUtils工具類的使用實例詳解
這篇文章主要介紹了SpringBoot?AnnotationUtils工具類的使用,使用自定義注解標記業(yè)務(wù)方法,原生Java獲取注解及AnnotationUtils工具類獲取方法,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-09-09
SpringCloud之Config配置中心與Redis分布式鎖詳解
這篇文章主要給大家介紹了SpringCloud Alibaba中Config配置中心,Redis分布式鎖,文中有詳細的代碼示例供大家參考,需要的朋友可以參考閱讀2023-05-05

