組件使用總結:使用 JAXB 實現 XML文件和java對象互轉

JAXB

JAXB:實現xml和java對象互轉

JAXB是一個業界的標準,實現XML文件和Java對象的互轉。
JAXB是JDK 的組成部分。咱們不須要下載第三方jar包 便可作到輕鬆轉換。
複製代碼

重要類和接口:

○ JAXBContext類,是應用的入口,用於管理XML/Java綁定信息。
	○ Marshaller接口,將Java對象序列化爲XML數據。
	○ Unmarshaller接口,將XML數據反序列化爲Java對象。
複製代碼

註解

從XML到Java對象的註解:
	○ @XmlType: 
	○ @XmlElement :將java對象的屬性映射爲xml的節點
	○ @XmlRootElement:此類對應xml的根元素
	○ @XmlAttribute :把java對象的屬性映射爲xml的屬性
	○ @XmlAccessorType :用於指定由java對象生成xml文件時對java對象屬性的訪問方式
	○ @XmlJavaTypeAdapter :在轉換比較複雜的對象時,如map類型或者格式化日期等。使用此註解時,須要本身寫一個XmlAdapter類
從Java對象到XML的註解:
	○ @XmlAccessorOrder :對java對象生成的xml元素進行排序
	○ @XmlTransient :定義某一字段或屬性不須要被映射爲XML
	○ @XmlElementWrapper :爲數組元素或集合元素定義一個父節點
複製代碼

工程實現

demo1:演示xml基本用法,演示@XmlRootElement 、@XmlAccessorType、@XmlElement的用法

基礎POJO類 ClassRoomModel包含一個變量name和變量StudentModel列表java

public class StudentModel {
    private int id; // 學號
    private String name; // 名稱
    private String sex; // 性別
}

@XmlRootElement(name = "classRoom")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ClassRoomModel {
    @XmlElement(name="name")
    private String name;

    @XmlElement(name="student")
    private List<StudentModel> studentModelList;
}
複製代碼

待轉化classroom.xmlgit

<?xml version="1.0" encoding="UTF-8"?>
<classRoom>
    <name>配置總名稱</name>
    <student>
        <id>1</id>
        <name>張三</name>
        <sex>男</sex>
    </student>
    <student>
        <id>2</id>
        <name>李四</name>
        <sex>女</sex>
    </student>
</classRoom>

複製代碼

測試類JAXBManager: 建立JAXBContext對象,根據JAXBContext對象建立Unmarshaller 對象,使用Unmarshaller 對象實現將xml轉化爲ClassRoomModel對象。 根據JAXBContext對象建立Marshaller 對象,使用Marshaller 實現將ClassRoomModel 對象轉化爲xml文件github

JAXBContext jaxbContext = JAXBContext.newInstance(ClassRoomModel.class);
// 從xml文件中讀取,並轉化爲java對象
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
InputStream classRoomInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/hry/java/xml/classroom.xml");
System.out.println(JAXBManager.class.getClassLoader().getResource(""));
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));

ClassRoomModel classRoomModel = (ClassRoomModel)unmarshaller.unmarshal(classRoomInputStream);
System.out.println(JSON.toJSONString(classRoomModel));

// 保存文件,將Java對象轉化爲xml文件
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(classRoomModel, new File("classroon-save.xml"));

複製代碼

demo2: 演示@XmlAttribute、@XmlJavaTypeAdapter、XmlAdapter用法

基礎POJO類: ClassRoomModel2包含一個變量name和變量StudentModel列表 此demo和上面的類不一樣,StudentModel2 是使用@XmlAttribute經過xml元素的屬性注入值,另外增長屬性Date對象數組

@XmlAccessorType(value = XmlAccessType.FIELD)
public class StudentModel2 {
    @XmlAttribute(name = "id")
    private int id; // 學號
    @XmlAttribute(name = "name")
    private String name; // 名稱
    @XmlAttribute(name = "sex")
    private String sex; // 性別
    @XmlAttribute(name = "birthDate")
    @XmlJavaTypeAdapter(value = DateXmlAdapter.class) // 配置日期轉化器
    private Date birthDate; // 生日
}

@XmlRootElement(name = "classRoom")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ClassRoomModel2 {
    @XmlElement(name="name")
    private String name;

    @XmlElement(name="student")
    private List<StudentModel2> studentModelList;
}
複製代碼

待轉化xml文件bash

<?xml version="1.0" encoding="UTF-8"?>
<classRoom>
    <name>配置總名稱</name>
    <student id="1" name="張三" sex="男" birthDate="1999-10-22" />
    <student id="2" name="李四" sex="女" birthDate="1997-12-23"  />
</classRoom>
複製代碼

XmlAdapter用法: StudentModel2 裏的成員變量birthDate的新註解@XmlJavaTypeAdapter(value = DateXmlAdapter.class),實現日期String和Date的相互轉化app

public class DateXmlAdapter extends XmlAdapter<String, Date> {
    // 時間
    private static final ThreadLocal<SimpleDateFormat> simpleDateFormatThreadLocalYYYYMMDD = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    @Override
    public Date unmarshal(String v) throws Exception {
        System.out.println(v);
        return simpleDateFormatThreadLocalYYYYMMDD.get().parse(v);
    }

    @Override
    public String marshal(Date v) throws Exception {
        System.out.println(v);
        return simpleDateFormatThreadLocalYYYYMMDD.get().format(v);
    }
}

複製代碼

測試類JAXBManager: 用法和第一個demo相同,詳細見代碼ide

public static void main(String[] args){
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(ClassRoomModel2.class);

            // 從xml文件中讀取,並轉化爲java對象
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            InputStream classRoomInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/hry/java/xml/classroom2.xml");
            System.out.println(JAXBManager2.class.getClassLoader().getResource(""));
            System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));

            ClassRoomModel2 classRoomModel = (ClassRoomModel2)unmarshaller.unmarshal(classRoomInputStream);
            System.out.println(JSON.toJSONString(classRoomModel));

            // 保存文件,將Java對象轉化爲xml文件
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.marshal(classRoomModel, new File("classroon-save2.xml"));

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

複製代碼

異常處理

若是不在類加上@XmlAccessorType(value = XmlAccessType.FIELD),則可能拋出以下異常。@XmlAccessorType的默認訪問級別是XmlAccessType.PUBLIC_MEMBER,所以,若是java對象中的private成員變量設置了public權限的getter/setter方法,就不要在private變量上使用@XmlElement和@XmlAttribute註解,不然在由java對象生成xml時會報同一個屬性在java類裏存在兩次的錯誤,異常以下:測試

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
類的兩個屬性具備相同名稱 "name"
	this problem is related to the following location:
		at public java.lang.String com.hry.java.xml.model.ClassRoomModel.getName()
		at com.hry.java.xml.model.ClassRoomModel
	this problem is related to the following location:
		at private java.lang.String com.hry.java.xml.model.ClassRoomModel.name
at com.hry.java.xml.model.ClassRoomModel
複製代碼

代碼

以上的詳細代碼見這裏Githubui

相關文章
相關標籤/搜索