2006-11-11
从一个实例看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文件时,如果没有工具支持,手工写,还是比较困难。
于是,一种新的处理方式用于对象和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文件时,如果没有工具支持,手工写,还是比较困难。
- 20:22
- 浏览 (11731)
- 评论 (13)
- 分类: webservices+xml
- 进入论坛
- 相关推荐
评论
pancras
2007-04-10
请问需要映射的两个java对象是怎么确定的?是自己写的,还是工具生成的?生成几个依据是什么?挺感兴趣的。比较有意思?能有在深入点的例子吗?感谢楼主分享!
还有,你那个头像挺逗的!
还有,你那个头像挺逗的!
glchengang
2006-12-01
用过jaxb,不过当时发现它不支持有继承结构的类的绑定,于是弃用了。
也许是自己对它了解不深吧。
也许是自己对它了解不深吧。
ryan
2006-11-17
引用
或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的)
这里的@XmlAccessorType,@XmlType 似乎只是for "Java-toSchema" ,用J2SE5.0中的元数据注释(Annotation)。
以前用过JAXB1.0,通过xjc会生成许多的Impl代码。但是今天使用了JDK5.0和JAXB2.0,发现一张xsd只是生成了一个ObjectFactory.java和xml schema中的root两个对象。十分诧异!难道2.0不需要那些自动生成的Impl代码了么?
请各位大师指点!
zyl
2006-11-15
guoshiguan 写道
看了楼主的文章,受益了, 不过还是有两个问题
-------------------------------
需要映射两个java对象,CustomerBo和AddressBo
java 对象可以通过xjc来生成。
或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的)
所以一般通过xjd自动生成
一个java对像要用两种工具生成吗,是什么工具,能不能告诉我全名啊,。
---------------------------------------
别忘了生成相应的xsd,或者dtd文件,
这个东东要用什么东东成生,
---------------------------------------
JAXBContext jc = JAXBContext.newInstance("mycompany.demo");
mycompany.demo是什么东东
-------------------------------
需要映射两个java对象,CustomerBo和AddressBo
java 对象可以通过xjc来生成。
或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的)
所以一般通过xjd自动生成
一个java对像要用两种工具生成吗,是什么工具,能不能告诉我全名啊,。
---------------------------------------
别忘了生成相应的xsd,或者dtd文件,
这个东东要用什么东东成生,
---------------------------------------
JAXBContext jc = JAXBContext.newInstance("mycompany.demo");
mycompany.demo是什么东东
不要意思打错了,是jaxb 自带的xjc命令,也支持ant task。根据schema生成相应的java源代码
xsd,可以通过jaxb的schemagen来生成
mycompany.demo 表示package 名称
zyl
2006-11-15
想不到有那么多人关注,我只是在学习jaxb当中,有几点需要说明一下:
jaxb,不只是一个单纯的工具库,感觉功能比较强大,需要和其他的jaxp相互协作。
jaxb关注的方面更广,能处理更为复杂的xml,
看一下以下代码就可以知道:
代码1,处理xpath
JAXBXpath jaxbXpath = new JAXBXpath(doc, binder);
(USAddress) jaxbXpath.evaluate("/purchaseOrder/shipTo");
代码2,直接更新xml
Binder<Node> binder=JAXBContext.createBinder()
JAXBElement<Items.Item> itemE = binder.unmarshal(
node,
Items.Item.class);
binder.Items.Item item = itemE.getValue();
item.setComment("qualifies for free shipping");
binder.updateXML(item);
当然为了处理复杂的xml,其复杂的配置也是不可少的。
xstream 我也了解过,不过大多数情况下我只是用来作为java Serializable 而使用。
对于处理一些比较简单的xml,xstream 是比较方便。
感觉两者的目的不太一致。有兴趣的可以去看看sun的jwsdp带的相关例子
jaxb,不只是一个单纯的工具库,感觉功能比较强大,需要和其他的jaxp相互协作。
jaxb关注的方面更广,能处理更为复杂的xml,
看一下以下代码就可以知道:
代码1,处理xpath
JAXBXpath jaxbXpath = new JAXBXpath(doc, binder);
(USAddress) jaxbXpath.evaluate("/purchaseOrder/shipTo");
代码2,直接更新xml
Binder<Node> binder=JAXBContext.createBinder()
JAXBElement<Items.Item> itemE = binder.unmarshal(
node,
Items.Item.class);
binder.Items.Item item = itemE.getValue();
item.setComment("qualifies for free shipping");
binder.updateXML(item);
当然为了处理复杂的xml,其复杂的配置也是不可少的。
xstream 我也了解过,不过大多数情况下我只是用来作为java Serializable 而使用。
对于处理一些比较简单的xml,xstream 是比较方便。
感觉两者的目的不太一致。有兴趣的可以去看看sun的jwsdp带的相关例子
pig345
2006-11-14
不好意思,我这里FCKeditor出错,连发了2次
pig345
2006-11-14
以前自己写,后来用过apache的betwixt,感觉比这里说的jaxb简单的多。
pig345
2006-11-14
以前自己写,后来用过apache的betwixt,感觉比这里说的jaxb简单的多。
lordhong
2006-11-14
xmx0632 写道
贴个xstream的:)
public class XStreamDateReader {
InputStream in = XStreamDateReader.class.getResourceAsStream("data.xml");
大哥,你手真快!。。。上面的DateReader应该是DataReader吧
guoshiguan
2006-11-14
看了楼主的文章,受益了, 不过还是有两个问题
-------------------------------
需要映射两个java对象,CustomerBo和AddressBo
java 对象可以通过xjc来生成。
或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的)
所以一般通过xjd自动生成
一个java对像要用两种工具生成吗,是什么工具,能不能告诉我全名啊,。
---------------------------------------
别忘了生成相应的xsd,或者dtd文件,
这个东东要用什么东东成生,
---------------------------------------
JAXBContext jc = JAXBContext.newInstance("mycompany.demo");
mycompany.demo是什么东东
-------------------------------
需要映射两个java对象,CustomerBo和AddressBo
java 对象可以通过xjc来生成。
或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的)
所以一般通过xjd自动生成
一个java对像要用两种工具生成吗,是什么工具,能不能告诉我全名啊,。
---------------------------------------
别忘了生成相应的xsd,或者dtd文件,
这个东东要用什么东东成生,
---------------------------------------
JAXBContext jc = JAXBContext.newInstance("mycompany.demo");
mycompany.demo是什么东东
zhangqidi
2006-11-14
一直用JiBX,觉得很好用,只要xml文件配置一下就ok了
xmx0632
2006-11-13
贴个xstream的:)
public class Customer {
protected Address address;
protected String name;
protected String id;
public String toString(){
return id+ " " + name + "@" + address;
}
}
import java.math.BigInteger;
public class Address {
protected String street;
protected String city;
protected BigInteger zip;
public String toString(){
return city+ " " + street + " " + zip;
}
}
import java.io.InputStream;
import com.thoughtworks.xstream.XStream;
public class XStreamDataReader {
public static void main(String[] args) {
XStream xstream = new XStream();
xstream.alias("customer", Customer.class);
xstream.alias("address", Address.class);
xstream.useAttributeFor("id", String.class);
InputStream in = XStreamDataReader.class.getResourceAsStream("data.xml");
Customer bo = (Customer)xstream.fromXML(in);
System.out.println(bo);
xstream.toXML(bo, new FileWriter("data1.xml"));//另存为...
}
}
lordhong
2006-11-13
看起来好麻烦啊!简单用途的话XStream就可以了
- 浏览: 114768 次

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
spring aop 2.0 编程(二 ...
依照你的例子,但是我test的时候出现以下结果我把class都放在package ...
-- by Ben.Sin -
ext 之我见
祝愿ext越走越远,把效率问题解决一下。
-- by InnocentBoy -
关于服务端生成js的构思
楼主的想法跟我不谋而合,想问一下remove相应的删除js脚本 ,是指删除以前返 ...
-- by gif98 -
关于服务端生成js的构思
stevenwang 写道你好像把方向搞反了。 为了减轻服务器的负载才选择了ri ...
-- by zyl -
关于服务端生成js的构思
你好像把方向搞反了。为了减轻服务器的负载才选择了rich client技术,你却 ...
-- by stevenwang






评论排行榜