网上找了很多jaxb 的资料自己留下印记,以免以后还得再找:
例子来源:
http://www.2cto.com/kf/201312/264168.html
http://terrencexu.iteye.com/blog/702089
http://blog.itpub.net/21147177/viewspace-604364/
还有一些找不到了 这几个应该够看懂了
还有俩个在线xml校验网站
http://www.bejson.com/go.php?u=http://www.bejson.com/xml2json/
http://www.freeformatter.com/xsd-generator.html#ad-output
当然以后不知道会不会 没有了
利用JAXB进行xml和javabean之间转换
Xml和javabean之间的互相转换是开发中常常遇到的问题,今天小试了一下JAXB,感觉真是太方便了,这里特此记录(JDK6中加入了JAXB,不需要额外导出包)
利用JAXB实现XML与Javabean之间的相互转换的大致思想:利用XML的生成相应的XSD或者DTD,然后利用该XSD或DTD生成对应的javabeanClass和ObjectFactory, 网上找个一个来描述了这个步骤:
一些名词:
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。
DTD (Documnet Type Definition) 即文档类型定义,是一套关于标记符的语法规则。它是XML1.0版规格得一部分,是XML文件的验证机制,属于XML文件组成的一部分。
XSD(XML Schema Definition,XSD) XML Schema 定义, 是基于 XML 的 DTD 替代者
开始转换
一. 利用XML生成相应XSD或者DTD
1. 生成XSD可以通过一个online工具完成.
网址: http://www.freeformatter.com/xsd-generator.html#ad-output
2. 生成DTD,通过一个java小工具:http://sourceforge.net/projects/xml2dtd/
二. 利用生成的XSD或者DTD生成java类:
1. 命令行的方式(jdk6的支持)
(a) XSD生成java: cmd--> cd xsd所在文件夹--> xjc –d . –p 包名 ./test.xsd
(b) DTD生成java: cmd --> cd DTD所在文件夹 --> xjc -dtd –d . –p 包名 ./test.dtd
2. Eclipse下面生成java类,此方法只针对xsd,选中你的xsd,右键:
然后选择包等操作,一步一步就可以生成了.
注意:XML里面最好不要包含value等敏感关键字,如果包含.先用别的名词替换,当生成javabean后再修改javabean.
三. 利用生成javabean来进行xml和java之间的转换
a> XML到javabean
Java代码-
File file = new File("C:/ML_OA_DATA.xml"); String xmlStr = FileUtils.readFileToString(file , "UTF-8"); Reader reader = new StringReader(xmlStr); Unmarshaller unmarshaller = JAXBContext.newInstance(Result.class).createUnmarshaller(); Result result = (Result) unmarshaller.unmarshal(reader); List list = result.getDocInfo().getField(); ListeFileList = result.getAttachments().getAttachment(); for (Attachment efile : eFileList) { System.out.println(efile.getFtpdir()); }
核心的就是这2句,1 注册对象,2反序列化 Unmarshaller unmarshaller = JAXBContext.newInstance(Result.class).createUnmarshaller(); Result result = (Result) unmarshaller.unmarshal(reader); unmarshal可以接收inputstream , read , file等.这里是通过string转换成reader b> javabean到XML Java代码-
Marshaller mashaller = JAXBContext.newInstance(Result.class).createMarshaller(); ObjectFactory factory = new ObjectFactory(); Result toxmlResult = factory.createResult(); //可选 开始 Field theField = factory.createResultDocInfoField(); theField.setColName("ssss"); DocInfo dii = factory.createResultDocInfo(); dii.getField().add(theField); toxmlResult.setDocInfo(dii); //可选 结束 mashaller.marshal(toxmlResult, new File("c:/outPut.xml"));
核心: 注册对象 和序列化
Marshaller mashaller = JAXBContext.newInstance(Result.class).createMarshaller();
mashaller.marshal(toxmlResult, new File("c:/outPut.xml"));
上面是第一个简单的列子
在java开发中使用XML几乎是每个程序员都会碰到的,目前可供我们选择的库也有很多,包括,dom4j, jaxen, SAX等等,本文将介绍如何使用JAXB进行Object-XML mapping.
JAXB目前已经集成到了JDK6中,但是还是推荐下载使用最新版的jaxb库, https://jaxb.dev.java.net/
从JAXB2.0开始,可以通过使用annotation进行Object-XMl mapping。
本文将通过以下步骤演示如何使用JAXB annotation绑定使用了namespace的XML文件
1. 创建employees.xml文件
2. 创建Employees.java和Employee.java绑定employees.xml
3. 创建package-info.java和jaxb.index文件
4. 创建XMLParser.java封装marshal/unmarshal操作
5. 创建Test.java运行测试
现在将逐步展开演示
1. 创建employees.xml文件
- <?xml version="1.0" encoding="utf-8" ?>
- <employees xmlns:admin="http://www.company.com/management/employees/admin">
- <admin:employee>
- <admin:userId>johnsmith@company.com</admin:userId>
- <admin:password>abc123_</admin:password>
- <admin:name>John Smith</admin:name>
- <admin:age>24</admin:age>
- <admin:gender>Male</admin:gender>
- </admin:employee>
- <admin:employee>
- <admin:userId>christinechen@company.com</admin:userId>
- <admin:password>123456</admin:password>
- <admin:name>Christine Chen</admin:name>
- <admin:age>27</admin:age>
- <admin:gender>Female</admin:gender>
- </admin:employee>
- </employees>
这是一个很普通的xml文件,用于展示组织内部的成员(employee)状况,这里有一点需要注意的是使用了namespace,这也是本文将要演示的重点。
2. 创建Employees.java和Employee.java绑定employees.xml
- package com.javaeye.terrencexu.jaxb;
- import java.util.ArrayList;
- import java.util.List;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- @XmlRootElement(name = "employees")
- public class Employees {
- @XmlElement(name = "employee", namespace=NameSpace.ADMIN_URI)
- private List<Employee> employees;
- public Employees() {
- employees = new ArrayList<Employee>();
- }
- public List<Employee> getEmployees() {
- return employees;
- }
- public void addEmployee(Employee employee) {
- employees.add(employee);
- }
- }
- package com.javaeye.terrencexu.jaxb;
- import javax.xml.bind.annotation.XmlElement;
- public class Employee {
- @XmlElement(name = "userId", namespace=NameSpace.ADMIN_URI)
- private String userId;
- @XmlElement(name = "password", namespace=NameSpace.ADMIN_URI)
- private String password;
- @XmlElement(name = "name", namespace=NameSpace.ADMIN_URI)
- private String name;
- @XmlElement(name = "age", namespace=NameSpace.ADMIN_URI)
- private int age;
- @XmlElement(name = "gender", namespace=NameSpace.ADMIN_URI)
- private String gender;
- public Employee() {
- }
- public Employee(String userId, String psw, String name, int age, Gender gender) {
- this.userId = userId;
- this.password = psw;
- this.name = name;
- this.age = age;
- this.gender = gender.getValue();
- }
- public String getUserId() {
- return userId;
- }
- public String getPassword() {
- return password;
- }
- public String getName() {
- return name;
- }
- public int getAge() {
- return age;
- }
- public String getGender() {
- return gender;
- }
- }
- package com.javaeye.terrencexu.jaxb;
- public class NameSpace {
- public static final String ADMIN_PREFIX = "admin";
- public static final String ADMIN_URI = "http://www.company.com/management/employees/admin";
- }
- package com.javaeye.terrencexu.jaxb;
- public enum Gender {
- MALE("Male"),
- FEMALE("Female");
- private String value;
- private Gender(String value) {
- this.value = value;
- }
- public String getValue() {
- return this.value;
- }
- }
3. 创建package-info.java和jaxb.index文件
创建package-info.java注册xmlns, 将该文件放在当前source code的package下面,如果不使用namespace可以不创建该文件
- @XmlSchema(
- xmlns={
- @XmlNs(prefix=NameSpace.ADMIN_PREFIX, namespaceURI=NameSpace.ADMIN_URI)
- }
- )
- package com.javaeye.terrencexu.jaxb;
- import javax.xml.bind.annotation.XmlNs;
- import javax.xml.bind.annotation.XmlSchema;
创建jaxb.index注册Employees, Employee,如果不使用包级context,可以不创建该文件
- Employees
- Employee
4. 创建XMLParser.java封装marshal/unmarshal操作
- package com.javaeye.terrencexu.jaxb;
- import java.io.InputStream;
- import java.io.StringWriter;
- import javax.xml.bind.JAXBContext;
- import javax.xml.bind.JAXBException;
- import javax.xml.bind.Marshaller;
- import javax.xml.bind.Unmarshaller;
- public final class XMLParser {
- private XMLParser() {}
- public static Object unmarshal(InputStream xml, Class<?> clazz) {
- Object obj = null;
- try {
- JAXBContext jc = JAXBContext.newInstance(clazz.getPackage().getName());
- Unmarshaller u = jc.createUnmarshaller();
- obj = u.unmarshal(xml);
- } catch (JAXBException e) {
- throw new RuntimeException("Can't unmarshal the XML file, error message: " + e.getMessage());
- }
- return obj;
- }
- public static String marshal(Object obj, Class<?> clazz) {
- String result = null;
- try {
- JAXBContext jc = JAXBContext.newInstance(clazz.getPackage().getName());
- Marshaller m = jc.createMarshaller();
- StringWriter writer = new StringWriter();
- m.marshal(obj, writer);
- result = writer.toString();
- } catch (JAXBException e) {
- throw new RuntimeException("Can't marshal the XML file, error message: " + e.getMessage());
- }
- return result;
- }
- }
5. 创建Test.java运行测试
- package com.javaeye.terrencexu.jaxb;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.util.List;
- public class Test {
- public static void main(String[] args) throws FileNotFoundException {
- testUnmarshal();
- testMarshal();
- }
- public static void testUnmarshal() throws FileNotFoundException {
- Employees employees = (Employees) XMLParser.unmarshal(
- new FileInputStream(new File("F:\\workspace\\JavaStudy\\test\\employees.xml")),
- Employees.class);
- List<Employee> employeeList = employees.getEmployees();
- if (employeeList != null && employeeList.size() > 0) {
- for (Employee employee : employeeList) {
- StringBuilder builder = new StringBuilder();
- builder.append("[UserID: ").append(employee.getUserId()).append(", ")
- .append("Password: ").append(employee.getPassword()).append(", ")
- .append("Name: ").append(employee.getName()).append(", ")
- .append("Age: ").append(employee.getAge()).append(", ")
- .append("Gender").append(employee.getGender()).append("]");
- System.out.println(builder.toString());
- }
- }
- }
- public static void testMarshal() {
- Employees employees = new Employees();
- employees.addEmployee(new Employee("johnsmith@company.com", "abc123_", "John Smith", 24, Gender.MALE));
- employees.addEmployee(new Employee("christinechen@company.com", "123456", "Christine Chen", 27, Gender.FEMALE));
- String result = XMLParser.marshal(employees, Employees.class);
- System.out.println(result);
- }
- }
6. 运行结果:
- [UserID: johnsmith@company.com, Password: abc123_, Name: John Smith, Age: 24, GenderMale]
- [UserID: christinechen@company.com, Password: 123456, Name: Christine Chen, Age: 27, GenderFemale]
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?><employees xmlns:admin="http://www.company.com/management/employees/admin"><admin:employee><admin:userId>johnsmith@company.com</admin:userId><admin:password>abc123_</admin:password><admin:name>John Smith</admin:name><admin:age>24</admin:age><admin:gender>Male</admin:gender></admin:employee><admin:employee><admin:userId>christinechen@company.com</admin:userId><admin:password>123456</admin:password><admin:name>Christine Chen</admin:name><admin:age>27</admin:age><admin:gender>Female</admin:gender></admin:employee></employees>
-
Marshaller mashaller = JAXBContext.newInstance(Result.class).createMarshaller(); ObjectFactory factory = new ObjectFactory(); Result toxmlResult = factory.createResult(); //可选 开始 Field theField = factory.createResultDocInfoField(); theField.setColName("ssss"); DocInfo dii = factory.createResultDocInfo(); dii.getField().add(theField); toxmlResult.setDocInfo(dii); //可选 结束 mashaller.marshal(toxmlResult, new File("c:/outPut.xml"));
最近项目中用到了JAXB以及Websphere Business Events,偶然从一个Defect中发现了这个问题,记录一下。
JavaBean中既包含简单类型属性,也包含复杂类型属性,如下面的Sample Code;
@XmlRootElement(name = "SampleRootBean", namespace = http://www.test.com/samplerootbean )
public class SampleRootBean {
....
@XmlElement(namespace = "http://www.test.com/samplerootbean")
private String ID;//简单类型
@XmlElement(namespace = "http://www.test.com/samplerootbean")
private String Name;//简单类型
@XmlElement(namespace = "http://www.test.com/samplerootbean")
private SampeChildBean[] SampleChileBean;//复杂类型
其通过JAXB的Marshaller序列化出的XML如下所示:
<SampleRootBean xmlns="http://www.test.com/samplerootbean " xmlns:ns2=http://www.test.com/samplechildben xmlns:ns3=http://www.ibm.com/xmlns/prod/websphere/j2ca/sap/sapidoccontrolrecord
其中的命名空间按照父到子的关系以此递增排列,如xmlns,xmlns:ns2,xmlns:ns3...
JaveBean中只包含复杂类型属性,如下面的Sample Code;
@XmlRootElement(name = "SampleRootBean", namespace = " http://www.test.com/samplerootbean")
public class SampRootBean{
...
@XmlElement(namespace = "http://www.test.com/samplerootbean")
private SampleChild1 C1;
@XmlElement(namespace = "http://www.test.com/samplerootbean")
private SampleChild2 C2;
这时起通过JAXB的Marshaller序列化出的XML如下所示:
<ns2:SampleRootBean xmlns="http://www.test.com/samplerootbean/c1 " xmlns:ns2="http://www.test.com/samplerootbean" xmlns:ns3="http://www.test.com/samplerootbean/c2 ">