JAXB-6 XML 应用案例
JAXB 直接操作 XML 文档,突出一个快捷!当然,也需要 XML 文档简洁明了。
假设要对如下的 XML 文档进行存取操作;
<class id="c001">
<name>Class A</name>
<students>
<student id="F20200212001">
<name>Student A</name>
<sex>man</sex>
</student>
<student id="F20200212002">
<name>Student B</name>
<sex>woman</sex>
</student>
</students>
</class>
班级 <class>
,学生集合<students>
,学生<student>
1、创建 Java Bean Class
参考:2 JAXB Annotation 注解
Student.java
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Student {
@XmlAttribute(name = "id")
private String id;
@XmlElement(name = "name")
private String name;
@XmlElement(name = "sex")
private String sex;
// getters, setters
}
SchoolClass.java,
@XmlRootElement(name = "class")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class SchoolClass {
@XmlAttribute(name = "id")
private String id;
@XmlElement(name = "name")
private String name;
@XmlElementWrapper(name = "students")
@XmlElement(name = "student")
private List<Student> students;
// getters, setters
}
使用 @XmlRootElement(name = "class")
声明根节点;
使用 @XmlAccessorType(value = XmlAccessType.FIELD)
声明使用属性处理 XML 映射关系;
使用 @XmlAttribute(name = "id")
声明 XML 节点的属性映射;
使用 @XmlElement(name = "name")
声明 XML 节点的元素映射;
使用功能 @XmlElementWrapper(name = "students")
声明集合元素在序列化时,使用 <students>
嵌套。
使用 @XmlElement(name = "student")
对 XML 集合元素 <student>
在反序列化时能够被识别;给 Student.java 类添加 @XmlRootElement(name = "student")
也能达到相同效果。
2、编写针对该 XML 文档的 XML 序列化与反序列化类
参考:JAXB API 封装
/**
* a single ton object that is responsible for converting XML to a SchoolClass object and SchoolClass to an XML.
*/
public class SchoolClassXmlSerializer {
// the singleton instance
private volatile static SchoolClassXmlSerializer instance;
// marshaller and unmarshaller
private final Marshaller marshaller; // java to xml
private final Unmarshaller unmarshaller; // xml to java
private SchoolClassXmlSerializer() throws JAXBException {
// create the JAXBContext object only here, to prevent memory leak
JAXBContext jc = JAXBContext.newInstance(SchoolClass.class);
marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
unmarshaller = jc.createUnmarshaller();
}
/**
* @return the singleton's instance (create it if necessary)
* @throws JAXBException if an error occurred while initializing the object
*/
public static SchoolClassXmlSerializer getInstance() throws JAXBException {
if (instance == null) {
synchronized (SchoolClassXmlSerializer.class) {
// double check the reference
if (instance == null) {
instance = new SchoolClassXmlSerializer();
}
}
}
return instance;
}
/**
* serializes a request object to an XML string
*
* @param request callback request
* @return the given request serialized to an XML string
* @throws JAXBException if an error occurs during marshaling
*/
public String serialize(SchoolClass request) throws JAXBException {
// output string
StringWriter writer = new StringWriter();
// marshal the request
synchronized (marshaller) {
marshaller.marshal(request, writer);
}
return writer.toString();
}
/**
* deserializes a request object from a given XML string
*
* @param xmlString XML input string
* @return callback request object that was deserialized from the input string
* @throws JAXBException if an error occurs during unmarshalling
* @throws ClassCastException if the deserialized object is not an instance of SchoolClass
*/
public SchoolClass deserialize(String xmlString) throws JAXBException {
StringReader reader = new StringReader(xmlString);
SchoolClass element;
synchronized (unmarshaller) {
element = (SchoolClass) unmarshaller.unmarshal(reader);
}
return element;
}
}
使用 单实例(singleton)
来防止高频调用内存溢出;
使用 JAXBContext.newInstance(SchoolClass.class);
创建 JAXB 的上下文,建立 Java Bean Class 与 XML 的映射关系;
使用 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
设置格式化 XML 文档输出;
使用 serialize
函数进行序列化;
使用 deserialize
函数进行反序列化;
3、测试解析与序列化功能
public class SchoolClassTest extends TestCase {
public void testSchoolClassXmlSerializer() throws IOException, JAXBException {
// resource path
String xmlPath = this.getClass().getClassLoader().getResource("data/class.xml").getPath();
// convert %20 into blank space, consider the Non-ASCII environment.
xmlPath = URLDecoder.decode(xmlPath);
// read XML string from File
String xmlDoc = readToString(xmlPath);
// instance of XmlSerializer class
SchoolClassXmlSerializer xmlSerializer = SchoolClassXmlSerializer.getInstance();
// deserialize XML doc
SchoolClass schoolClass = xmlSerializer.deserialize(xmlDoc);
// assert: check available of deserialize object
// ...
// demo: change the deserialize object
schoolClass.setId("c002");
// serialize object
xmlDoc = xmlSerializer.serialize(schoolClass);
// write XML string back to File
writeToFile(xmlPath, xmlDoc);
}
private String readToString(String fileName) {
String encoding = "UTF-8";
File file = new File(fileName);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
try {
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
return new String(filecontent, encoding);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void writeToFile(String fileName, String fileContent) {
try {
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
osw.write(fileContent);
osw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
上一章:JAXB-5 动态 XML 生成
目录:学习 JAXB
下一章:无