前言
在之前的所有spring boot教程中,我們都只提到和用到了針對html和json格式的請求與響應處理。那么對于xml格式的請求要如何快速的在controller中包裝成對象,以及如何以xml的格式返回一個對象呢?
什么是xml文件格式
我們要給對方傳輸一段數據,數據內容是“too young,too simple,sometimes naive”,要將這段話按照屬性拆分為三個數據的話,就是,年齡too young,閱歷too simple,結果sometimes naive。我們都知道程序不像人,可以體會字面意思,并自動拆分出數據,因此,我們需要幫助程序做拆分,因此出現了各種各樣的數據格式以及拆分方式。比如,可以是這樣的數據為“too young,too simple,sometimes naive”然后按照逗號拆分,第一部分為年齡,第二部分為閱歷,第三部分為結果。也可以是這樣的數據為“too_young* too_simple*sometimes_naive”從數據開頭開始截取前面十一個字符,去掉號并把下劃線替換為空格作為第一部分,再截取接下來的十一個字符同樣去掉并替換下劃線為空格作為第二部分,最后把剩下的字符同樣去號體會空格作為第三部分。這兩種方式都可以用來容納數據并能夠被解析,但是不直觀,通用性也不好,而且如果出現超過限定字數的字符串就容納不了,也可能出現數據本身就下劃線字符導致需要做轉義。基于這種情況,出現了xml這種數據格式, 上面的數據用xml表示的話可以是這樣
實現原理:消息轉換器(message converter)
在擴展上述問題之前,我們先要知道spring boot中處理http請求的實現是采用的spring mvc。而在spring mvc中有一個消息轉換器這個概念,它主要負責處理各種不同格式的請求數據進行處理,并包轉換成對象,以提供更好的編程體驗。
在spring mvc中定義了httpmessageconverter接口,抽象了消息轉換器對類型的判斷、對讀寫的判斷與操作,具體可見如下定義:
1
2
3
4
5
6
7
8
9
10
11
12
|
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格式的消息轉換,就必須要使用對應的轉換器。spring mvc中默認已經有一套采用jackson實現的轉換器mappingjackson2xmlhttpmessageconverter。
擴展實現
第一步:引入xml消息轉換器
在傳統spring應用中,我們可以通過如下配置加入對xml格式數據的消息轉換實現:
1
2
3
4
5
6
7
8
9
|
@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應用不用像上面這么麻煩,只需要加入jackson-dataformat-xml依賴,spring boot就會自動引入mappingjackson2xmlhttpmessageconverter的實現:
1
2
3
4
|
<dependency> <groupid>com.fasterxml.jackson.dataformat</groupid> <artifactid>jackson-dataformat-xml</artifactid> </dependency> |
同時,為了配置xml數據與維護對象屬性的關系所要使用的注解也在上述依賴中,所以這個依賴也是必須的。
第二步:定義對象與xml的關系
做好了基礎擴展之后,下面就可以定義xml內容對應的java對象了,比如:
1
2
3
4
5
6
7
8
9
10
11
|
@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以及構造函數。@jacksonxmlrootelement、@jacksonxmlproperty注解是用來維護對象屬性在xml中的對應關系。
上述配置的user對象,其可以映射的xml樣例如下(后續可以使用上述xml來請求接口):
1
2
3
4
|
<user> <name>aaaa</name> <age> 10 </age> </user> |
第三步:創建接收xml請求的接口
完成了要轉換的對象之后,可以編寫一個接口來接收xml并返回xml,比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@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應用,通過postman等請求工具,嘗試一下這個接口,可以看到請求xml,并且返回了經過處理后的xml內容。
案例代碼
可以通過下面兩個倉庫中查閱chapter3-1-8目錄:
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://blog.didispace.com/spring-boot-xml-httpmessageconverter/