0
点赞
收藏
分享

微信扫一扫

从一个实例看jaxb的强大

读取xml对于应用软件来说是一个必不可少的工作,当然现在的jdk也提供了很好的处理xml方式,读写xml的库也挺多,包括有名的dom4j,不管使用任何的代码库,对于xml只是一个解析工作而已,不能马上绑定到java 对象。对于对象,每次都需要set 或者get相应的属性,当然也可以使用map 来保存xml配置。
    于是,一种新的处理方式用于对象和xml之间的映射就变得非常需要,还好sun提供了jaxb,一种很方便的方式来处理java对象和xml内容。下面通过一个实例来体会一下。
    看一下如下的xml

<?xml version="1.0"?> 
 <customer id="No1"> 
     <name>Alice Smith</name> 
     <address> 
         <street>123 Maple Street</street> 
         <city>Cambridge</city> 
         <zip>12345</zip> 
     </address> 
 </customer>


别忘了生成相应的xsd,或者dtd文件,这是主要的配置:

xsd: 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    
     <xs:complexType name="Customer"> 
       <xs:sequence> 
          <xs:element name="address" type="Address"/> 
          <xs:element name="name" type="xs:string"/> 
       </xs:sequence> 
        <xs:attribute name="id" type="xs:string"/>       
     </xs:complexType> 
    
       <xs:complexType name="Address"> 
       <xs:sequence> 
          <xs:element name="street" type="xs:string"/> 
          <xs:element name="city" type="xs:string"/> 
          <xs:element name="zip" type="ZipCodeType"/> 
        </xs:sequence> 
    </xs:complexType> 
   
     <xs:simpleType name="ZipCodeType"> 
       <xs:restriction base="xs:integer"> 
          <xs:minInclusive value="10000"/> 
          <xs:maxInclusive value="99999"/> 
       </xs:restriction> 
     </xs:simpleType> 
     <xs:element name="customer" type="Customer"/> 
     <xs:element name="address" type="Address"/> 
 </xs:schema>


需要映射两个java对象,CustomerBo和AddressBo
java 对象可以通过xjc来生成。
或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的)
所以一般通过xjd自动生成

@XmlAccessorType(AccessType.FIELD) 
 @XmlType(name = "Customer", propOrder = { 
     "address", 
     "customerName" 
 }) 
 public class CustomerBo { 

     protected Address address; 

     @XmlElement(name = "name") 
     protected String customerName; 

     @XmlAttribute 
     protected String id; 

     public Address getAddress() { 
         return address; 
     } 

     public String getCustomerName() { 
         return customerName; 
     } 

     public String getId() { 
         return id; 
     } 

     public void setAddress(Address value) { 
         this.address = value; 
     } 

     public void setCustomerName(String value) { 
         this.customerName = value; 
     } 

     public void setId(String value) { 
         this.id = value; 
     } 
 } 


 public class Address { 

     protected String street; 

     protected String city; 

     @XmlElement(name = "zip") 
     protected BigInteger zipCode; 

     public String getStreet() { 
         return street; 
     } 

     public void setStreet(String value) { 
         this.street = value; 
     } 

     public String getCity() { 
         return city; 
     } 

     public void setCity(String value) { 
         this.city = value; 
     } 

     public BigInteger getZipCode() { 
         return zipCode; 
     } 

     public void setZipCode(BigInteger value) { 
         this.zipCode = value; 
     } 

 } 

 定义jxb绑定文件: 
 <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="customer.xsd" node="/xs:schema">   
           
    <jxb:globalBindings 
          fixedAttributeAsConstantProperty="false" 
          collectionType="java.util.Vector" 
          typesafeEnumBase="xs:NCName" 
          choiceContentProperty="false" 
          typesafeEnumMemberName="generateError" 
          enableFailFastCheck="false"  
          generateIsSetMethod="false" 
          underscoreBinding="asCharInWord"/> 
    <jxb:schemaBindings> 
       <jxb:package name="mycompany.demo"> 
         <jxb:javadoc><![CDATA[<body>Package level documentation for generated package mycompany.demo.</body>]]> 
         </jxb:javadoc> 
       </jxb:package> 
       <jxb:nameXmlTransform> 
         <jxb:elementName suffix="Element"/> 
       </jxb:nameXmlTransform> 
     </jxb:schemaBindings>  

     //需要绑定的元素 
    <jxb:bindings node="//xs:complexType[@name='Customer']"> 
        //绑定的类 
       <jxb:class name="CustomerBo"> 
         <jxb:javadoc>A <b>todo..</jxb:javadoc> 
       </jxb:class> 
       <jxb:bindings node=".//xs:element[@name='name']"> 
            //绑定的属性 
            <jxb:property name="customerName"/> 
         </jxb:bindings> 
     </jxb:bindings>  
          
     <jxb:bindings node="//xs:complexType[@name='Address']"> 
       <jxb:class name="AddressBo"> 
         <jxb:javadoc><![CDATA[First line of documentation for a <b>Address</b>.]]></jxb:javadoc> 
       </jxb:class> 
       <jxb:bindings node=".//xs:element[@name='zip']"> 
          <jxb:property name="zipCode"/> 
       </jxb:bindings> 
     </jxb:bindings> 
             
    </jxb:bindings> 
 </jxb:bindings> 

     看着比较复杂,其实挺好理解,当然可以不需要这个绑定文件,也可以绑定相应的java 类,但需要元素名称和类名称完全一致,而且属性也要一致。 

     看一下jaxb是如何来读入xml的: 
         //主要的环境类,主要读取ObjectFactory这个类,这是由xjc生成的。 
         JAXBContext jc = JAXBContext.newInstance("mycompany.demo"); 
         Unmarshaller u = jc.createUnmarshaller(); 
         JAXBElement customerE = (JAXBElement) u.unmarshal(new FileInputStream( 
                                 "customer.xml")); 
         CustomerBo bo = (CustomerBo) customerE.getValue(); 
     就是这么简单 

     写入也比较简单: 
         JAXBContext jc = JAXBContext.newInstance("mycompany.demo"); 
         Marshaller marshaller=jc.createMarshaller(); 
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
         customerE.setValue(bo); 
         marshaller.marshal( customerE,new FileOutputStream("test.xml"));


 
    在webservices中jaxb的作用是明显的,当然也有不方便的地方,比如定义binding.jaxb文件时,如果没有工具支持,手工写,还是比较困难。


举报

相关推荐

0 条评论