首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > XML SOAP >

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

2012-11-10 
一个jaxb的例子看java object和xml之间的转换这段时间在研究o/x mapping,即Java object和xml之间的转换以

一个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 marshallingJAXBElement<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 packageJAXBContext 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>


我已经将演示项目的完整代码打包上传到附件了,测试通过,方便网友们下载,有不足之处愿与大家切磋
<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;    }}


热点排行