`
cuishen
  • 浏览: 297397 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

一个jaxb的例子看java object和xml之间的转换

阅读更多
这段时间在研究o/x mapping,即Java object和xml之间的转换以及xml文件验证的问题,自己也动手开发了一个小的演示例子,如下所示:

--------开发环境-----
1.jdk1.5
2.jwsdp2.0(Java Web Services Developer Pack 2.0, sun的官网上有的下)
3.程序中需要用到的jar包:
%jwsdp2.0安装目录下%/jaxb/lib/jaxb-api.jar
%jwsdp2.0安装目录下%/jaxb/lib/jaxb-impl.jar
%jwsdp2.0安装目录下%/sjsxp/lib/jsr173_api.jar
%jwsdp2.0安装目录下%/jwsdp-shared/lib/activation.jar
4.开发工具:eclipse3.2
---------------------

定义一个XML schema文件--library.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="librarys" type="librarys"/>
<xs:complexType name="librarys">
	<xs:sequence>
		<xs:element name="library" minOccurs="1" maxOccurs="unbounded">
			<xs:complexType>
				<xs:sequence>
					<xs:element name="name" type="xs:string"/>
					<xs:element name="layer" type="xs:int"/>
					<xs:element name="row" type="xs:int"/>
					<xs:element name="book" type="book"/>
				</xs:sequence>
			</xs:complexType>
		</xs:element>
	</xs:sequence>
</xs:complexType>
<xs:complexType name="book">
	<xs:sequence>
		<xs:element name="bookID" type="xs:string"/>
		<xs:element name="bookName" type="xs:string"/>
		<xs:element name="borrowDate" type="xs:date"/>
		<xs:element name="user" type="user"/>
	</xs:sequence>
	<xs:attribute name="description" type="xs:string"/>
</xs:complexType>
<xs:complexType name="user">
	<xs:sequence>
		<xs:element name="userID" type="xs:string"/>
		<xs:element name="userName" type="xs:string"/>
		<xs:element name="userAge" type="xs:int"/>
	</xs:sequence>
</xs:complexType>
</xs:schema>


再定义jwsdp的xjc工具的binding文件---binding.xjb
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings schemaLocation="library.xsd" node="/xs:schema"><!-- schemaLocation属性是xsd文件的相对路径 -->
    <jxb:globalBindings 
	fixedAttributeAsConstantProperty="true" 
	collectionType="java.util.ArrayList" 
	typesafeEnumBase="xs:NCName" 
	choiceContentProperty="false" 
	typesafeEnumMemberName="generateError" 
	enableFailFastCheck="false" 
	generateIsSetMethod="false" 
	underscoreBinding="asCharInWord"/>
    <jxb:schemaBindings>
        <jxb:package name="com.cuishen.o_x_mapping.object"/>
        <!-- 这里是生成的JAVA类文件存放包名 -->
        <jxb:nameXmlTransform>
	    		 <jxb:elementName suffix="Element"/>
				</jxb:nameXmlTransform>
    </jxb:schemaBindings>
    <!-- 这里是定义xsd中一个复合类型与Java类的映射(如果要修改才定义,不修改则不需要) -->
    <jxb:bindings node="//xs:complexType[@name='librarys']">
        <jxb:class name="Librarys"/>
    </jxb:bindings>
    <jxb:bindings node="//xs:complexType[@name='book']">
        <jxb:class name="Book"/>
        <!-- 这里是定义复合类型的一个元素名称与Java类中属性的映射(如果要修改才定义,不修改则不需要) -->
        <jxb:bindings node=".//xs:element[@name='bookID']">
            <jxb:property name="id"/>
        </jxb:bindings>
    </jxb:bindings>
    <jxb:bindings node="//xs:complexType[@name='user']">
        <jxb:class name="User"/>
        <!-- 这里是定义复合类型的一个元素名称与Java类中属性的映射(如果要修改才定义,不修改则不需要) -->
        <jxb:bindings node=".//xs:element[@name='userID']">
            <jxb:property name="id"/>
        </jxb:bindings>
    </jxb:bindings>
  </jxb:bindings>
</jxb:bindings>


注意!binding文件的编码格式要用UTF-8,如果直接把代码粘到eclipse里编码格式就不是UTF-8了,这时xjc工具就要报错了,解决办法就是把这个文件用UltraEdit工具转一下。
可以通过binding文件和xsd文件用jaxb自带的xjc工具自动生成java object,是不是很棒啊^_^

现在写o/x mapping的测试主类----Main.java
package com.cuishen.o_x_mapping;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import com.cuishen.o_x_mapping.object.Book;
import com.cuishen.o_x_mapping.object.Librarys;
import com.cuishen.o_x_mapping.object.User;
import com.cuishen.o_x_mapping.object.ObjectFactory;

import com.cuishen.o_x_mapping.utils.FileUtils;;

/**
 * o/x mapping测试主类
 * @author cuishen
 * @date 2008-4-2
 * @version 1.0
 */
public class Main {
	public static void object2xml() {
		try {
			JAXBContext context = JAXBContext.newInstance("com.cuishen.o_x_mapping.object");
			
			Librarys libs = new Librarys();
			List<Librarys.Library> libList = libs.getLibrary();
			
			User usr = createUser("1011", 28, "cuishen");
			Book book = createBook("成长比成功更重要", getDate(), "成功励志书", "88-91-211", usr);			
			libList.add(createLibrary("上海图书馆", 2, 4, book));
			
			usr = createUser("1017", 22, "sanmao");
			book = createBook("七龙珠", getDate(), "漫画", "34-16-310", usr);			
			libList.add(createLibrary("徐汇图书馆", 3, 11, book));
			
			// create an element for marshalling
			JAXBElement<Librarys> element = (new ObjectFactory()).createLibrarys(libs);
			
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			m.setProperty("jaxb.encoding", "gbk");
			m.marshal(element, System.out);
			File xmlFile = FileUtils.makeFile(getXmPath());
			OutputStream ot = new FileOutputStream(xmlFile);
			m.marshal(element, ot);
		} catch (JAXBException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void xml2object(Unmarshaller u) {
		try {
			//JAXBContext jc = JAXBContext.newInstance( "com.cuishen.o_x_mapping.object" );
			
			//Unmarshaller u = jc.createUnmarshaller();
			
			// unmarshal a po instance document into a tree of Java content
			// objects composed of classes from the com.cuishen.o_x_mapping.object package.
			JAXBElement poe = (JAXBElement)u.unmarshal(new FileInputStream(getXmPath()));
			Librarys librarys = (Librarys)poe.getValue();
			
			List libList = librarys.getLibrary();
			for(int i = 0; i < libList.size(); i++) {
				Librarys.Library lib = (Librarys.Library)libList.get(i);
				System.out.println("librarys ==> ");
				System.out.println("===> library :");
				System.out.println("=========> layer " + lib.getLayer());
				System.out.println("=========> name " + lib.getName());
				System.out.println("=========> row " + lib.getRow());
				System.out.println("=========> book :");
				Book book = lib.getBook();
				System.out.println("=============> id " + book.getId());
				System.out.println("=============> borrowDate " + book.getBorrowDate());
				System.out.println("=============> name " + book.getBookName());
				System.out.println("=============> desc " + book.getDescription());
				System.out.println("=============> user :");
				User usr = book.getUser();
				System.out.println("==================> userID " + usr.getId());
				System.out.println("==================> userName " + usr.getUserName());
				System.out.println("==================> Age " + usr.getUserAge());            	
			}
			
		} catch( JAXBException je ) {
			je.printStackTrace();
		} catch( IOException ioe ) {
			ioe.printStackTrace();
		}
	}
	
	/**
	 * 对xml文件解组时的验证
	 * @return boolean
	 */
	public static Unmarshaller validate() {
		// create a JAXBContext capable of handling classes generated into
		// the com.cuishen.o_x_mapping.object package
		JAXBContext jc;
		Unmarshaller u = null;
		try {
			jc = JAXBContext.newInstance( "com.cuishen.o_x_mapping.object" );
			
			u = jc.createUnmarshaller();
			
			SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			try {
				Schema schema = sf.newSchema(new File(getXSDPath()));
				u.setSchema(schema);
				u.setEventHandler(
						new ValidationEventHandler() {
							public boolean handleEvent(ValidationEvent ve) {
								if (ve.getSeverity() == ValidationEvent.WARNING || ve.getSeverity() != ValidationEvent.WARNING) {
									ValidationEventLocator vel = ve.getLocator();
									System.out.println("Line:Col[" + vel.getLineNumber() + ":" + vel.getColumnNumber() + "]:" + ve.getMessage());
									return false;
								}
								return true;
							}
						}
				);
			} catch (org.xml.sax.SAXException se) {
				System.out.println("Unable to validate due to following error.");
				se.printStackTrace();
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return u;
	}
	
	private static String getXmPath() throws MalformedURLException {
		String xmlPath = FileUtils.extractDirPath(FileUtils.extractDirPath(Main.class.getClassLoader().getResource(".").toString()));
		xmlPath = FileUtils.makeFilePath(xmlPath, "src/com/cuishen/o_x_mapping/xml/library.xml");
		URL url = new URL(xmlPath);
		return url.getPath();
	}
	
	private static String getXSDPath() throws MalformedURLException {
		String xsdPath = FileUtils.extractDirPath(FileUtils.extractDirPath(Main.class.getClassLoader().getResource(".").toString()));
		xsdPath = FileUtils.makeFilePath(xsdPath, "library.xsd");
		URL url = new URL(xsdPath);
		System.out.println("xsd path ==========> " + url.getPath());
		return url.getPath();		
	}
	
	public static void main(String args[]) {		
		System.out.println("======== object to xml ...");
		object2xml();
		System.out.println("======== xml to object ...");
		xml2object(validate());
	}
	public static Librarys.Library createLibrary(String name, int layer, int row, Book book) {
		Librarys.Library library = new Librarys.Library();
		library.setName(name);
		library.setLayer(layer);
		library.setRow(row);
		library.setBook(book);
		return library;
	}
	public static Book createBook(String name, XMLGregorianCalendar date, String desc, String id, User usr) {
		Book book = new Book();
		book.setBookName(name);
		book.setBorrowDate(date);
		book.setDescription(desc);
		book.setId(id);
		book.setUser(usr);
		return book;
	}
	public static User createUser(String id, int age, String name) {
		User usr = new User();
		usr.setId(id);
		usr.setUserAge(age);
		usr.setUserName(name);
		return usr;
	}
	private static XMLGregorianCalendar getDate() {
		try {
			return DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar());
		} catch (DatatypeConfigurationException e) {
			throw new Error(e);
		}
	}
}


以上代码的核心是xml文件的编组和解组,用到了接口javax.xml.bind.Marshaller(Marshaller 类负责管理将 Java 内容树序列化回 XML 数据的过程,它提供了基本的编组方法marshal), 以及接口javax.xml.bind.Unmarshaller(Unmarshaller 类管理将 XML 数据反序列化为新创建的 Java 内容树的过程,并可在解组时有选择地验证 XML 数据。它针对各种不同的输入种类提供各种重载的 unmarshal 方法。), 至于xml文件的验证是在解组的时候,调用方法unmarshal会触发验证的机制,验证xml文件是否符合schema的规范。

下面定义build.xml,用ant工具来完成整个项目的编译和运行,方便快捷,^_^
<project basedir="." default="run">
  <!--这里是jwsdp的安装目录 -->
  <property name="jwsdp.home" value="d:\Sun\jwsdp-2.0"/>
  <!--这里是log4j的安装目录 -->
  <property name="log4j.home" value="D:\conserv\o-x-mapping\implement\lib"/>
  <path id="xjc.classpath">
    <pathelement path="src"/>
    <pathelement path="bin"/>
    <pathelement path="lib"/>
    <pathelement path="schemas"/>
    <!--for use with bundled ant-->
    <fileset dir="${jwsdp.home}" includes="jaxb/lib/*.jar"/>
    <fileset dir="${jwsdp.home}" includes="sjsxp/lib/*.jar"/>
    <fileset dir="${jwsdp.home}" includes="jwsdp-shared/lib/activation.jar"/>
    <fileset dir="${jwsdp.home}" includes="jwsdp-shared/lib/resolver.jar"/>
    <fileset dir="${log4j.home}" includes="log4j-1.2.5.jar"/>
  </path>
  <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
	<classpath refid="xjc.classpath" />
  </taskdef>
  
    <!--compile Java source files-->
  <target name="compile" description="Compile all Java source files">
    <echo message="Compiling the schema..." />
    <!-- mkdir dir="src" /-->
    <xjc schema="library.xsd" binding="binding.xjb" destdir="src"/>
    <echo message="Compiling the java source files..." />
    <mkdir dir="bin" />
    <javac destdir="bin" debug="on">
      <src path="src" />
      <classpath refid="xjc.classpath" />
    </javac>
  </target>

  <target name="run" depends="compile" description="Run the sample app">
    <echo message="Running the sample application..." />
    <java classname="com.cuishen.o_x_mapping.Main" fork="true">
      <classpath refid="xjc.classpath" />
    </java>
  </target>
  
</project>


我已经将演示项目的完整代码打包上传到附件了,测试通过,方便网友们下载,有不足之处愿与大家切磋
分享到:
评论
6 楼 Joo 2008-05-19  
请问为什么针对这样的schema为什么会生成这样的java类呢?
应该怎么写binding.xjb文件?貌似<javaType/>属性也不行啊
  <xs:element name="ForecastPartner">
    <xs:complexType>
      <xs:sequence minOccurs="1" maxOccurs="unbounded">
        <xs:element ref="GlobalPartnerReferenceTypeCode" />
        <xs:element ref="PartnerDescription" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "globalPartnerReferenceTypeCodeAndPartnerDescription"
})
@XmlRootElement(name = "ForecastPartner")
public class ForecastPartner {

    @XmlElements({
        @XmlElement(name = "PartnerDescription", required = true, type = PartnerDescription.class),
        @XmlElement(name = "GlobalPartnerReferenceTypeCode", required = true, type = String.class)
    })
    protected List<Object> globalPartnerReferenceTypeCodeAndPartnerDescription;

    /**
     * Gets the value of the globalPartnerReferenceTypeCodeAndPartnerDescription property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the globalPartnerReferenceTypeCodeAndPartnerDescription property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getGlobalPartnerReferenceTypeCodeAndPartnerDescription().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link PartnerDescription }
     * {@link String }
     * 
     * 
     */
    public List<Object> getGlobalPartnerReferenceTypeCodeAndPartnerDescription() {
        if (globalPartnerReferenceTypeCodeAndPartnerDescription == null) {
            globalPartnerReferenceTypeCodeAndPartnerDescription = new ArrayList<Object>();
        }
        return this.globalPartnerReferenceTypeCodeAndPartnerDescription;
    }

}



5 楼 Joo 2008-04-21  
如果已经有Schema的.xsd的文件了,直接用xjc生成Java class就行了把?为什么还需要一个binding.xjb文件

4 楼 RuhaiTsia 2008-04-14  
如果library.xsd中包含其他的schema
应该怎么设置Unmarshaller的schema?
3 楼 cuishen 2008-04-10  
Joo 写道
用jaxb处理XML得到的java对象的变化能不能反映到Xml中


jaxb处理xml得到java object,当这个object中封装的数据发生变化后,调用上例中方法object2xml()将这个object写到xml里面覆盖原来的xml不就行啦
2 楼 Joo 2008-04-10  
用jaxb处理XML得到的java对象的变化能不能反映到Xml中
1 楼 RuhaiTsia 2008-04-10  
很好的例子,谢谢分享!

相关推荐

    JAXB工具类 xml转为java对象 java对象转为xml

    Java Architecture for XML Binding (JAXB) 是Java平台中用于处理XML和Java对象之间转换的一个标准API。它使得在Java应用程序中使用XML数据变得更加方便,无需手动编写大量的转换代码。本教程将详细介绍JAXB如何实现...

    webservice之使用jaxb把xml转换Object或把对象转换成xml文件

    JAXB与其他XML处理技术(如DOM、SAX、StAX)相比,更注重于对象模型与XML之间的绑定,适用于需要频繁进行对象与XML转换的场景。而DOM适合处理小规模的XML文档,SAX和StAX则适用于大文件流式处理。 总结,JAXB是Java...

    JAVA JAXB 解析XML嵌套子节点为字符串

    在Java开发中,JAXB(Java Architecture for XML Binding)是一个标准的API,用于将XML文档与Java对象之间进行互相转换。这个技术对于处理XML数据,尤其是解析和生成XML文档非常有用。当我们面临XML文档中存在嵌套子...

    java list和xml互转例子

    总之,Java List与XML之间的转换是数据交换和持久化的重要手段,而dom4j库提供了一种方便的方式来实现这种转换。通过熟练掌握这些概念和方法,开发者可以更好地在Java应用程序中处理结构化的数据。

    java对象转换成xml格式

    下面是一个简单的例子: ```java import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.XMLOutputFactory; XMLOutputFactory factory = XMLOutputFactory.newInstance(); XMLStreamWriter ...

    java+xml联合编程简单例子

    3. **JAXB(Java Architecture for XML Binding)**:JAXB允许我们将Java对象和XML文档之间进行自动转换。Java类可以被编译为XML Schema,反之亦然,这简化了数据的序列化和反序列化过程。 4. **JDOM(Java ...

    JAXBUtil使用JAXB进行xml和bean互转

    JAXB(Java Architecture for XML Binding)是Java平台的一个标准API,它提供了一种自动化的机制,用于在XML文档和Java对象之间进行映射和转换。本篇文章将深入探讨如何使用JAXBUtil来实现XML和bean之间的互转,并...

    java中xml与object的应用 (XMLEncoder应用)

    `XMLEncoder`是`java.beans`包的一部分,它提供了`encode`方法,可以将一个Java对象转换成XML文本。在使用`XMLEncoder`之前,你需要确保你的对象拥有合适的getter和setter方法,因为`XMLEncoder`会通过反射机制访问...

    java中读写XML文件

    首先,我们需要引入处理XML文件的Java API,即Java的DOM(Document Object Model)和SAX(Simple API for XML)解析器。DOM解析器将整个XML文档加载到内存中,形成一个树形结构,便于遍历和操作。而SAX解析器则采用...

    java xml.java操作XML文档

    5. JAXB (Java Architecture for XML Binding): 这是一个用于将Java对象转换为XML表示和反之的框架。JAXB允许我们在Java类和XML之间自动映射,简化了数据序列化和反序列化的过程。 6. Transformer API: 提供了将XML...

    Xml.rar_java xml_xml_xml 数据库_xml数据库

    在Java中,JAXB(Java Architecture for XML Binding)是用于对象到XML以及XML到对象之间转换的标准API,它可以自动将Java对象序列化为XML,并反序列化回Java对象。而JDBC(Java Database Connectivity)则是Java...

    java读取XML文件内容小程序

    这个上下文知道如何将XML转换为Java对象。 3. **反序列化XML**:使用`Unmarshaller`接口从XML文件创建Java对象。`Unmarshaller.unmarshal()`方法接受一个`File`对象或`InputStream`,并返回一个代表XML内容的对象。...

    详 解Java解析XML

    Java 解析 XML 主要涉及两种主流方法:DOM(Document Object Model)和 SAX(Simple...如果需要在Java对象和XML之间进行绑定,JAXB是一个强大的工具。理解这些解析方法的特点和应用场景,可以帮助你更好地处理XML数据。

    XML操作文档及使用例子程序(一个完整的例子)

    总之,这个压缩包提供了一个从实践中学习XML操作的好机会,通过运行和分析代码,你可以掌握XML解析、操作、转换以及Java与XML交互的各种技术。无论你是初学者还是经验丰富的开发者,这个例子都会是提升技能的宝贵...

    基于java的开发源码-转换xml.zip

    虽然XStream是一个强大的工具,但Java还有其他处理XML的库,如JAXB(Java Architecture for XML Binding),DOM(Document Object Model),SAX(Simple API for XML),以及StAX(Streaming API for XML)。...

    java四种xml读写demo

    在这个例子中,`Employee`是一个Java类,其属性对应于XML文件中的元素。 以上四种方法各有优缺点,选择哪种取决于具体的应用场景。DOM适合小型文件,易于操作;SAX和StAX适合处理大型文件,节省内存;JAXB则在对象...

    xml格式的字符串转换成List

    在Java中,可以使用DOM(Document Object Model)、SAX(Simple API for XML)或者JAXB(Java Architecture for XML Binding)。在.NET环境中,有XmlSerializer或LINQ to XML等工具。 2. **创建数据模型**:为了...

    dom4j_XML.rar_DOM4J_dom4j xml java_java xml_读写xml

    5. **DOM4J与JAXB(Java Architecture for XML Binding)对比**:虽然两者都可以处理XML,但DOM4J更侧重于底层的XML操作,而JAXB则用于将Java对象和XML之间进行自动转换,更适用于对象和XML映射的需求。 6. **示例...

    json和xml工具类

    总结来说,`AppUtil`工具类是一个集成了JSON和XML数据转换功能的实用程序,它简化了Java应用中数据格式的转换过程。通过调用其中的静态方法,开发者能够快速地将Java对象转换为JSON或XML格式,从而满足不同场景下的...

    xml_bjsxt.rar_java xml_xml

    Java作为一种强大的编程语言,提供了多种API来处理XML,包括DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for XML)。本实例将探讨如何在Java中解析XML文件并生成XML文件。 1. *...

Global site tag (gtag.js) - Google Analytics