JAXB解析xml轉(zhuǎn)換成類的實(shí)現(xiàn)方式
項目需要將一些公共配置項寫成xml文件,啟動時轉(zhuǎn)化成對應(yīng)的類。
查找了一些資料,發(fā)現(xiàn)JAXB完全可以滿足自己的功能需求。
pom依賴
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>主要注解
@XmlRootElement
@XmlRootElement定義xml根節(jié)點(diǎn)的信息。主要功能如下:
1. 將元素與XML模式類型相關(guān)聯(lián)
@XmlRootElement
class Point {
int x;
int y;
Point(int _x,int _y) {x=_x;y=_y;}
}
//Example: Code fragment corresponding to XML output
marshal( new Point(3,5), System.out);
<!-- Example: XML output -->
<point>
<x> 3 </x>
<y> 5 </y>
</point>
//注釋在模式中生成全局元素聲明。全局元素聲明與類映射到的XML模式類型相關(guān)聯(lián)。
<!-- Example: XML schema definition -->
<xs:element name="point" type="point"/>
<xs:complexType name="point">
<xs:sequence>
<xs:element name="x" type="xs:int"/>
<xs:element name="y" type="xs:int"/>
</xs:sequence>
</xs:complexType>2. 將全局元素與類所屬的XML模式類型相關(guān)聯(lián)
@XmlRootElement(name="PriceElement")
public class USPrice {
@XmlElement
public java.math.BigDecimal price;
}
Example: XML schema definition -->
<xs:element name="PriceElement" type="USPrice"/>
<xs:complexType name="USPrice">
<xs:sequence>
<xs:element name="price" type="xs:decimal"/>
</sequence>
</xs:complexType>@XmlElement
@XmlElement可以將xml元素轉(zhuǎn)為對應(yīng)的實(shí)體屬性值??赊D(zhuǎn)化普通屬性、數(shù)組、對象
1. 將公共非靜態(tài)非最終字段映射到本地元素
public class USPrice {
@XmlElement(name="itemprice")
public java.math.BigDecimal price;
}
<!-- Example: Local XML Schema element -->
<xs:complexType name="USPrice"/>
<xs:sequence>
<xs:element name="itemprice" type="xs:decimal" minOccurs="0"/>
</sequence>
</xs:complexType>2. 映射到可nullable元素。
public class USPrice {
@XmlElement(nillable=true)
public java.math.BigDecimal price;
}
<!-- Example: Local XML Schema element -->
<xs:complexType name="USPrice">
<xs:sequence>
<xs:element name="price" type="xs:decimal" nillable="true" minOccurs="0"/>
</sequence>
</xs:complexType>3. 映射到可nullable元素且必填的元素。
public class USPrice {
@XmlElement(nillable=true, required=true)
public java.math.BigDecimal price;
}
<!-- Example: Local XML Schema element -->
<xs:complexType name="USPrice">
<xs:sequence>
<xs:element name="price" type="xs:decimal" nillable="true" minOccurs="1"/>
</sequence>
</xs:complexType>@XmlElements
@XmlElements可以將不同的xml節(jié)點(diǎn)轉(zhuǎn)換為實(shí)體數(shù)組對象。
public class Foo {
XmlElements(
XmlElement(name="A", type=Integer.class),
XmlElement(name="B", type=Float.class)
)
public List items;
}
// items = [1,2.5]時,得到的xml為
<A> 1 </A>
<B> 2.5 </B>
...
<!-- XML Schema fragment -->
<xs:complexType name="Foo">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="A" type="xs:int"/>
<xs:element name="B" type="xs:float"/>
<xs:choice>
</xs:sequence>
</xs:complexType>映射到用另一個元素包裹的元素列表
// Mapped code fragment
public class Foo {
XmlElementWrapper(name="bar")
XmlElements(
XmlElement(name="A", type=Integer.class),
XmlElement(name="B", type=Float.class)
}
public List items;
}映射結(jié)果
<!-- XML Schema fragment -->
<xs:complexType name="Foo">
<xs:sequence>
<xs:element name="bar">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="A" type="xs:int"/>
<xs:element name="B" type="xs:float"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>使用適配器根據(jù)類型更改元素名稱
class Foo {
XmlJavaTypeAdapter(QtoPAdapter.class)
XmlElements({
XmlElement(name="A",type=PX.class),
XmlElement(name="B",type=PY.class)
})
Q bar;
}
XmlType abstract class P {...}
XmlType(name="PX") class PX extends P {...}
XmlType(name="PY") class PY extends P {...}
<!-- XML Schema fragment -->
<xs:complexType name="Foo">
<xs:sequence>
<xs:element name="bar">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="A" type="PX"/>
<xs:element name="B" type="PY"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>@XmlElementWrapper
圍繞XML表示生成包裝器元素。
這主要是為了在集合周圍生成一個包裝器XML元素。
通過這個 @XmlElementWrapper注解可以減少包裝類的創(chuàng)建。
//Example: code fragment
int[] names;
// XML Serialization Form 1 (Unwrapped collection)
<names> ... </names>
<names> ... </names>
// XML Serialization Form 2 ( Wrapped collection )
<wrapperElement>
<names> value-of-item </names>
<names> value-of-item </names>
....
</wrapperElement>@XmlElementWrapper 需要配合 @XmlElement 一起使用
@XmlList
@XmlList注釋允許在單個元素中將多個值表示為空格分隔的標(biāo)記
@XmlRootElement
class Foo {
@XmlElement
@XmlList
List<String> data;
}
the above code will produce XML like this:
<foo>
<data>abc def</data>
</foo>@XmlAttribute
@XmlAttribute可以獲取到xml節(jié)點(diǎn)的屬性字段值
@XmlElementRef
該注解所在屬性是某些子類的父類,起到引用的作用。
同時標(biāo)注得有@XmlElementRef的類屬性,其子類上需要使用@XmlRootElement標(biāo)注,否則轉(zhuǎn)換異常,提示找不到具體的引用實(shí)現(xiàn)。
另外,轉(zhuǎn)換時,需要將其子類的class一起傳遞到JAXBContext上下文中,否則也無法轉(zhuǎn)換。
@XmlTransient
通常與 @XmlElement 須搭配使用的。
@XmlElement用在屬性上,用于指定生成xml的節(jié)點(diǎn)名,@XmlTransient用在對應(yīng)的getter方法上,起到關(guān)聯(lián)的作用。
@XmlAccessorOrder
控制JAXB 綁定類中屬性和字段的排序。
其他
@XmlValue、@XmlEnum、@XmlEnumValue
實(shí)現(xiàn)
定義xml信息
<person>
<id>111111</id>
<name>lijie</name>
<address>
<province></province>
<city></city>
<detail></detail>
</address>
<attr property="1231321" />
<items>
<item>afgafdafd</item>
<item>adfadfadfa</item>
</items>
</person>定義類
這里通過使用@XmlElementWrapper注解配合可以減少包裝類的創(chuàng)建
@XmlRootElement(name = "person")
public class Person{
@XmlElement(name = "id")
String id;
@XmlElement(name = "name")
String name;
@XmlElement(name = "address")
Address addrss;
@XmlElement(name = "attr")
Attributes attributes;
@XmlElementWrapper(name = "items")
@XmlElement(name = "item")
List<Item> items;
}
public class Address{
@XmlElement(name = "province")
String province;
@XmlElement(name = "city")
String city;
}
public class Item{
@XmlElement(name = "item")
String des;
}
public class Attributes{
@XmlAttribute(name = "property")
String des;
}轉(zhuǎn)換
xml轉(zhuǎn)換為實(shí)體類
ClassPathResource resource = new ClassPathResource("xml/SnmpTrapHitRules.xml");
BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getStream()));
JAXBContext jaxbContext = JAXBContext.newInstance(SnmpTrapHitRuleDto.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
snmpTrapHitRuleDto = (SnmpTrapHitRuleDto) unmarshaller.unmarshal(reader);實(shí)體類轉(zhuǎn)成xml
// 創(chuàng)建Person對象
Person person = new Person("張三", 30);
// 創(chuàng)建JAXBContext對象
JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
// 創(chuàng)建Marshaller對象
Marshaller marshaller = jaxbContext.createMarshaller();
// 設(shè)置格式化輸出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// 將Java對象轉(zhuǎn)換為XML字符串
StringWriter stringWriter = new StringWriter();
marshaller.marshal(person, stringWriter);問題
JAXB要求將注解放到對應(yīng)的set/get方法上,但是由于我們可能使用的時lombok,沒有顯示的說明get/set方法,這時候會報錯:類的兩個屬性具有相同名稱。
解決辦法是在類上加入注解 @XmlAccessorType
@XmlAccessorType
類級別的注解。定義這個類中的何種類型需要映射到XML。
解釋起來有點(diǎn)拗口,可以通過它的屬性值更好理解這個參數(shù)的意義。
- 參數(shù) value
參數(shù) value 可以接受4個指定值,這幾個值是枚舉類型,方便調(diào)用:
XmlAccessType.FIELD:映射這個類中的所有字段到XMLXmlAccessType.PROPERTY:映射這個類中的屬性(get/set方法)到XMLXmlAccessType.PUBLIC_MEMBER:將這個類中的所有public的field或property同時映射到XML(默認(rèn))XmlAccessType.NONE:不映射
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- java報錯:javax.xml.bind.JAXBException:?JAXB解決辦法
- SpringBoot基于JAXB實(shí)現(xiàn)天地圖路徑規(guī)劃結(jié)果XML轉(zhuǎn)JSON
- Springboot集成JAXB返回xml格式
- 使用JAXBContext 設(shè)置xml節(jié)點(diǎn)屬性
- 使用JAXBContext輕松實(shí)現(xiàn)Java和xml的互相轉(zhuǎn)換方式
- java利用JAXB實(shí)現(xiàn)對象和xml互相轉(zhuǎn)換方法與實(shí)例詳解
- Jaxb2實(shí)現(xiàn)JavaBean與xml互轉(zhuǎn)的方法詳解
- java使用jaxb操作xml示例
相關(guān)文章
淺談Java8 的foreach跳出循環(huán)break/return
這篇文章主要介紹了Java8 的foreach跳出循環(huán)break/return,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
SpringBoot中@Valid對List校驗(yàn)失效問題的有效解決方法
在Spring Boot應(yīng)用開發(fā)中,我們經(jīng)常需要對傳入的請求參數(shù)進(jìn)行校驗(yàn),以確保數(shù)據(jù)的合法性和安全性,然而,當(dāng)我們嘗試對列表(List)類型的參數(shù)進(jìn)行校驗(yàn)時,可能會遇到校驗(yàn)失效的問題,本文將詳細(xì)探討這一問題的失效原因,并提供有效的解決方法,需要的朋友可以參考下2025-07-07
java實(shí)現(xiàn)多文件上傳至本地服務(wù)器功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多文件上傳至本地服務(wù)器功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01
SpringBoot如何進(jìn)行參數(shù)校驗(yàn)實(shí)例詳解
開發(fā)過程中,后臺的參數(shù)校驗(yàn)是必不可少的,下面這篇文章主要給大家介紹了關(guān)于SpringBoot如何進(jìn)行參數(shù)校驗(yàn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01
解決spring-boot2.0.6中webflux無法獲得請求IP的問題
這幾天在用 spring-boot 2 的 webflux 重構(gòu)一個工程,寫到了一個需要獲得客戶端請求 IP 的地方,在寫的過程中遇到很多問題,下面小編通過一段代碼給大家介紹解決spring-boot2.0.6中webflux無法獲得請求IP的問題,感興趣的朋友跟隨小編一起看看吧2018-10-10
Java 并發(fā)編程學(xué)習(xí)筆記之核心理論基礎(chǔ)
編寫優(yōu)質(zhì)的并發(fā)代碼是一件難度極高的事情。Java語言從第一版本開始內(nèi)置了對多線程的支持,這一點(diǎn)在當(dāng)年是非常了不起的,但是當(dāng)我們對并發(fā)編程有了更深刻的認(rèn)識和更多的實(shí)踐后,實(shí)現(xiàn)并發(fā)編程就有了更多的方案和更好的選擇。本文是對并發(fā)編程的核心理論做了下小結(jié)2016-05-05
關(guān)于@ApiModel和@ApiModelProperty的使用
這篇文章主要介紹了關(guān)于@ApiModel和@ApiModelProperty的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11

