JAXB 實現java對象與xml之間互相轉換

JAXB 實現java對象與xml之間互相轉換

一、簡介

      JAXB(Java Architecture for XML Binding) 是一個業界的標準,是一項可以根據XML Schema產生Java類的技術。該過程中,JAXB也提供了將XML實例文檔反向生成Java對象樹的方法,並能將Java對象樹的內容重新寫到 XML實例文檔。

      Jaxb 2.0是JDK 1.6的組成部分。我們不需要下載第三方jar包 即可做到輕鬆轉換。Jaxb2使用了JDK的新特性,如:Annotation、GenericType等,需要在即將轉換的JavaBean中添加annotation註解。

 

二、重要概念

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

首先熟悉一下JAXB實現對象與xml互轉時常用的一些註解使用:

1.@XmlRootElement,用於類級別的註解,對應xml的跟元素。通過name屬性定義這個根節點的名稱。

2.@XmlAccessorType,定義映射這個類中的何種類型都需要映射到xml。(如果不存在@XmlAccessorType,默認使用XmlAccessType.PUBLIC_MEMBER註解)

  參數:XmlAccessType.FIELD: java對象中的所有成員變量。

  XmlAccessType.PROPERTY:java對象中所有通過getter/setter方式訪問的成員變量。

  XmlAccessType.PUBLIC_MEMBER:java對象中所有的public訪問權限的成員變量和通過getter/setter方式訪問的成員變量。

  XmlAccessType.NONE: java對象的所有屬性都不映射爲xml的元素。

3.@XmlAttribute,用於把java對象的屬性映射爲xml的屬性,並可通過name屬性爲生成的xml屬性指定別名。

4.@XmlElement,指定一個字段或get/set方法映射到xml的節點。通過name屬性定義這個根節點的名稱。

5.@XmlElementWrapper,爲數組或集合定義一個父節點。通過name屬性定義這個父節點的名稱。

 

下面來看一個例子:

先定義一個學生類,Student如下:

package xmldemo;

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

/**
 * @author aionbo
 * @type_name Student
 * @description TODO
 * @date 2017年3月7日 上午11:36:25
 */
public class Student {

	String name; // 姓名
	String sex; // 性別
	int number; // 學號
	String className; // 班級
	List<String> hobby; // 愛好

	public Student() {
	}

	public Student(String name, String sex, int number, String className,
			List<String> hobby) {
		this.name = name;
		this.sex = sex;
		this.number = number;
		this.className = className;
		this.hobby = hobby;
	}

	@XmlAttribute(name = "name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@XmlAttribute(name = "sex")
	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@XmlAttribute(name = "number")
	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	@XmlElement(name = "className")
	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	@XmlElementWrapper(name = "hobbys")
	@XmlElement(name = "hobby")
	public List<String> getHobby() {
		return hobby;
	}

	public void setHobby(List<String> hobby) {
		this.hobby = hobby;
	}
}

切記,如果java對象屬性同時添加了get和set方法,註解不能定義在屬性的定義上,只需在get或者set方法上定義一個即可,否則jaxb會報錯!!如下:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
  Class has two properties of the same name "name"

 

然後再定義學生集合類,StudentList如下:

package xmldemo;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author aionbo
 * @type_name StudentList
 * @description TODO
 * @date 2017年3月7日 上午11:40:18
 */
@XmlRootElement(name = "list")
public class StudentList {

	List<Student> students; // 所有學生信息的集合

	@XmlElement(name = "student")
	public List<Student> getStudents() {
		return students;
	}

	public void setStudents(List<Student> students) {
		this.students = students;
	}
}

 

最後寫xml和java對象互轉的類(通過Marshaller類實現將對象轉換爲xml,同時也可利用Unmarshaller類進行xml轉換爲類):

1.java對象轉換爲xml:

package xmldemo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

/**
 * @author aionbo
 * @type_name BeanToXML
 * @description TODO
 * @date 2017年3月7日  上午11:43:36
 */
public class BeanToXML {

	       /**
	      * java對象轉換爲xml文件
	      * @param xmlPath  xml文件路徑
	      * @param load    java對象.Class
	      * @return    xml文件的String
	      * @throws JAXBException    
	      */
	     public static String beanToXml(Object obj,Class<?> load) throws JAXBException{
	         JAXBContext context = JAXBContext.newInstance(load);
	         Marshaller marshaller = context.createMarshaller();
	         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
	         marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
	         StringWriter writer = new StringWriter();
	         marshaller.marshal(obj,writer);
	         return writer.toString();
	     }
	     public static void main(String[] args) throws JAXBException, IOException {
	             List<String> hobby = new ArrayList<>();
	             hobby.add("籃球");
	             hobby.add("音樂");
	             hobby.add("乒乓球");
	             
	             List<Student> studentList = new ArrayList<>();
	             
	             Student st = new Student("張三","男",10001,"尖子班",hobby);
	             studentList.add(st);
	             Student st1 = new Student("李四","男",10002,"普通班",hobby);
	             studentList.add(st1);
	             Student st2 = new Student("莉莉","女",10003,"普通班",hobby);
	             studentList.add(st2);
	             
	             StudentList students = new StudentList();
	             students.setStudents(studentList);
	             //轉換
	             String str =  BeanToXML.beanToXml(students, StudentList.class);
	             
	             //寫入到xml文件中
	             File file=new File("C:\\Users\\Administrator\\Desktop\\test.xml");
	             if(!file.exists()){
	 				file.createNewFile();
	 			}
	             BufferedWriter bfw = new BufferedWriter(new FileWriter(file));
	             bfw.write(str);
	             bfw.close();
	     }
}


測試生成的xml文件如下圖:


2.xml轉換爲java對象:

package xmldemo;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

/**
 * @author aionbo
 * @type_name XMLToBean
 * @description TODO
 * @date 2017年3月7日  上午11:54:07
 */
public class XMLToBean {

		/**
	     * xml文件配置轉換爲對象
	     * @param xmlPath  xml文件路徑
	     * @param load    java對象.Class
	     * @return    java對象
	     * @throws JAXBException    
	     * @throws IOException
	     */
	    public static Object xmlToBean(String xmlPath,Class<?> load) throws JAXBException, IOException{
	        JAXBContext context = JAXBContext.newInstance(load);  
	        Unmarshaller unmarshaller = context.createUnmarshaller();
	        File file=new File(xmlPath);
            if(!file.exists()){
				file.createNewFile();
			}
	        Object object = unmarshaller.unmarshal(file);
	        return object;
	    }
	    
	    public static void main(String[] args) throws IOException, JAXBException {
	        String xmlPath = "C:\\Users\\Administrator\\Desktop\\test.xml";
	        Object object = XMLToBean.xmlToBean(xmlPath,StudentList.class);
	        StudentList students = (StudentList)object;
	        List<Student> studentList = students.getStudents();
	        
	        for(int i=0;i<studentList.size();i++){
	            System.out.println(studentList.get(i).name);
	            System.out.println(studentList.get(i).sex);
	            System.out.println(studentList.get(i).number);
	            System.out.println(studentList.get(i).className);
	            for(String str :studentList.get(i).hobby){
	                System.out.print(str+" ");
	            }
	            System.out.println();
	            System.out.println("-------------");
	        }
	    }
}


測試打印的結果如下:

張三

10001
尖子班
籃球 音樂 乒乓球 
-------------
李四

10002
普通班
籃球 音樂 乒乓球 
-------------
莉莉

10003
普通班
籃球 音樂 乒乓球 
-------------

有不明白的可以聯繫我,互相交流!
jaxb雖然挺實用,但是在xml轉java對象時xml文件不能配置錯了,必須嚴格按照自己定義的java對象的註解來編寫xml文件,否則jaxb裏面報錯很難查錯!!!


發佈了20 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章