JAXB解析xml轉(zhuǎn)換成類的實(shí)現(xiàn)方式
項(xiàng)目需要將一些公共配置項(xiàng)寫成xml文件,啟動(dòng)時(shí)轉(zhuǎn)化成對(duì)應(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)為對(duì)應(yīng)的實(shí)體屬性值??赊D(zhuǎn)化普通屬性、數(shù)組、對(duì)象
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ù)組對(duì)象。
public class Foo {
XmlElements(
XmlElement(name="A", type=Integer.class),
XmlElement(name="B", type=Float.class)
)
public List items;
}
// items = [1,2.5]時(shí),得到的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>映射到用另一個(gè)元素包裹的元素列表
// 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表示生成包裝器元素。
這主要是為了在集合周圍生成一個(gè)包裝器XML元素。
通過這個(gè) @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注釋允許在單個(gè)元素中將多個(gè)值表示為空格分隔的標(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
該注解所在屬性是某些子類的父類,起到引用的作用。
同時(shí)標(biāo)注得有@XmlElementRef的類屬性,其子類上需要使用@XmlRootElement標(biāo)注,否則轉(zhuǎn)換異常,提示找不到具體的引用實(shí)現(xiàn)。
另外,轉(zhuǎn)換時(shí),需要將其子類的class一起傳遞到JAXBContext上下文中,否則也無法轉(zhuǎn)換。
@XmlTransient
通常與 @XmlElement 須搭配使用的。
@XmlElement用在屬性上,用于指定生成xml的節(jié)點(diǎn)名,@XmlTransient用在對(duì)應(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對(duì)象
Person person = new Person("張三", 30);
// 創(chuàng)建JAXBContext對(duì)象
JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
// 創(chuàng)建Marshaller對(duì)象
Marshaller marshaller = jaxbContext.createMarshaller();
// 設(shè)置格式化輸出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// 將Java對(duì)象轉(zhuǎn)換為XML字符串
StringWriter stringWriter = new StringWriter();
marshaller.marshal(person, stringWriter);問題
JAXB要求將注解放到對(duì)應(yīng)的set/get方法上,但是由于我們可能使用的時(shí)lombok,沒有顯示的說明get/set方法,這時(shí)候會(huì)報(bào)錯(cuò):類的兩個(gè)屬性具有相同名稱。
解決辦法是在類上加入注解 @XmlAccessorType
@XmlAccessorType
類級(jí)別的注解。定義這個(gè)類中的何種類型需要映射到XML。
解釋起來有點(diǎn)拗口,可以通過它的屬性值更好理解這個(gè)參數(shù)的意義。
- 參數(shù) value
參數(shù) value 可以接受4個(gè)指定值,這幾個(gè)值是枚舉類型,方便調(diào)用:
XmlAccessType.FIELD:映射這個(gè)類中的所有字段到XMLXmlAccessType.PROPERTY:映射這個(gè)類中的屬性(get/set方法)到XMLXmlAccessType.PUBLIC_MEMBER:將這個(gè)類中的所有public的field或property同時(shí)映射到XML(默認(rèn))XmlAccessType.NONE:不映射
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- java報(bào)錯(cuò):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)對(duì)象和xml互相轉(zhuǎn)換方法與實(shí)例詳解
- Jaxb2實(shí)現(xiàn)JavaBean與xml互轉(zhuǎn)的方法詳解
- java使用jaxb操作xml示例
相關(guān)文章
Java 8函數(shù)式接口Function BiFunction DoubleFunction
這篇文章主要為大家介紹了Java 8函數(shù)式接口Function BiFunction DoubleFunction區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
詳解JavaScript中的函數(shù)聲明和函數(shù)表達(dá)式
這篇文章主要介紹了詳解JavaScript中的函數(shù)聲明和函數(shù)表達(dá)式,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08
實(shí)例解析Java的Jackson庫中的數(shù)據(jù)綁定
這篇文章主要介紹了Java的Jackson庫中的數(shù)據(jù)綁定,這里分為通常的簡(jiǎn)單數(shù)據(jù)綁定與全數(shù)據(jù)綁定兩種情況來講,需要的朋友可以參考下2016-01-01
Java實(shí)現(xiàn)連接kubernates集群的兩種方式詳解

