以下内容是个人对jaxb技术的总结及操作实例讲解:
1、什么是jaxb?
也就是说jaxb是一项数据绑定技术,它将xml文件映射成一个个的java类,程序员通过操作这些类就可以对xml文件中的元素进行读取等操作,同样程序员也可以改变这些类的属性,最后映射到xml文件中,这样做可以把程序员的主要精力放在业务逻辑上,并且也更符合面向对象的思想,而无需像使用DOM4J等技术一样需要处理一个个的xml节点,但是jaxb技术还不够成熟,对于映射的数据类型的控制,以及对语义等价的实现的还不够完美。
2、使用xjc工具生成xml对应的java类
如果xml结构比较简单,建议手动的编写java类即可,如下示例
command.xml文件为:
<?xml version="1.0" encoding="UTF-8"?> <Command-Mappers> <Comand-Mapper> <CommandReg>shutdown</CommandReg> <ClassName>com.yinhoo.ca.command.ShutDownCmdExecutor</ClassName> </Comand-Mapper> </Command-Mappers>
对应的CommandMapper.java为:
* @(#)CommandMapper.java 2011-2-12
package com.yinhoo.ca.dto;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* Mapped for command.xml
*
* @author chenming
* @date 2011-2-12
* @version $Revision$
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Command-Mappers")
public class CommandMapper {
private List<ComandMapper> cmdMapperList;
/**
* @return the cmdMapperList
*/
public List<ComandMapper> getCmdMapperList() {
return cmdMapperList;
}
/**
* @param cmdMapperList
* the cmdMapperList to set
*/
public void setCmdMapperList(List<ComandMapper> cmdMapperList) {
this.cmdMapperList = cmdMapperList;
}
@XmlElement(name = "Comand-Mapper")
@XmlType(name = "Comand-Mapper")
@XmlAccessorType(XmlAccessType.FIELD)
public static class ComandMapper {
@XmlElement(name = "CommandReg")
private String commandReg;
@XmlElement(name = "ClassName")
private String className;
/**
* @return the commandReg
*/
public String getCommandReg() {
return commandReg;
}
/**
* @param commandReg
* the commandReg to set
*/
public void setCommandReg(String commandReg) {
this.commandReg = commandReg;
}
/**
* @return the className
*/
public String getClassName() {
return className;
}
/**
* @param className
* the className to set
*/
public void setClassName(String className) {
this.className = className;
}
}
}
稍微复杂的例子encrypt_list.xml为:
<?xml version="1.0" encoding="UTF-8"?> <EncryptInfo> <DoEncrypt>true</DoEncrypt> <CaServer>10.10.10.40</CaServer> <CaPort>50000</CaPort> <EncryptList> <Encrypt> <type>FILE</type> <value>conf\configs.xml</value> </Encrypt> <Encrypt> <type>FOLD</type> <value>conf\domains\</value> <!-- 排除的文件列表,以 逗号分隔. --> <exclude>.svn,gmail.com.xml,china.com.xml</exclude> </Encrypt> </EncryptList> </EncryptInfo>
对应的EncryptMapper.java为:
* @(#)EncryptMapper.java 2011-2-14
package com.yinhoo.ca.dto;
import java.io.Serializable;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* 对应encrypt_list.xml
*
* @author chenming
* @date 2011-2-14
* @version $Revision$
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "EncryptInfo")
public class EncryptMapper {
@XmlElement(name = "DoEncrypt")
private Boolean doEncrypt;
@XmlElement(name = "CaServer")
private String caServer;
@XmlElement(name = "CaPort")
private Integer caPort;
@XmlElementWrapper(name = "EncryptList")
private List<Encrypt> encryptList;
/**
* @return the doEncrypt
*/
public Boolean getDoEncrypt() {
return doEncrypt;
}
/**
* @param doEncrypt
* the doEncrypt to set
*/
public void setDoEncrypt(Boolean doEncrypt) {
this.doEncrypt = doEncrypt;
}
/**
* @return the caServer
*/
public String getCaServer() {
return caServer;
}
/**
* @param caServer
* the caServer to set
*/
public void setCaServer(String caServer) {
this.caServer = caServer;
}
/**
* @return the caPort
*/
public Integer getCaPort() {
return caPort;
}
/**
* @param caPort
* the caPort to set
*/
public void setCaPort(Integer caPort) {
this.caPort = caPort;
}
/**
* @return the encryptList
*/
public List<Encrypt> getEncryptList() {
return encryptList;
}
/**
* @param encryptList
* the encryptList to set
*/
public void setEncryptList(List<Encrypt> encryptList) {
this.encryptList = encryptList;
}
@XmlElement(name = "Encrypt")
@XmlType(name = "Encrypt")
@XmlAccessorType(XmlAccessType.FIELD)
public static class Encrypt {
@XmlElement(name = "type")
private String type;
@XmlElement(name = "value")
private String value;
@XmlElement(name = "exculde")
private String exclude;
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type
* the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* @return the value
*/
public String getValue() {
return value;
}
/**
* @param value
* the value to set
*/
public void setValue(String value) {
this.value = value;
}
/**
* @return the exclude
*/
public String getExclude() {
return exclude;
}
/**
* @param exclude
* the exclude to set
*/
public void setExclude(String exclude) {
this.exclude = exclude;
}
}
}
否则需生成xml对应的xsd文件,然后利用xsd文件生成xml对应的java类。关于如何利用xml生成对应的xsd文件可参考以下链接(待完善):
http://sunxboy.iteye.com/blog/411513/
本文采用的xml文件为guitars.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <guitars> <guitar id="10021"> <builder luthier="true">Ryan</builder> <model>Mission Grand Concert</model> <back-sides>Brazilian Rosewood</back-sides> <top>Adirondack Spruce</top> <notes> <![CDATA[ Just unbelievable... this guitar has all the tone & resonance you could ever want. I mean, <<WOW!!!>> This is a lifetime guitar. ]]> </notes> </guitar> <guitar id="0923"> <builder smallShop="true">Bourgeois</builder> <model>OMC</model> <back-sides>Bubinga</back-sides> <top>Adirondack Spruce</top> </guitar> <guitar id="11091"> <builder>MartinCompany</builder> <model>OM-28VR</model> <back-sides>Indian Rosewood</back-sides> <top bearclaw="true">Sitka Spruce</top> <notes>It's certainly true that Martin isn't the only game in town anymore. Still, the OM-28VR is one of their best models... and this one has some fabulous bearclaw to boot. Nice specimen of a still-important guitar manufacturer. </notes> </guitar> </guitars>
对应的guitars.xsd为:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="back-sides" type="xs:string"/> <xs:element name="builder"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="luthier" default="false"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="true"/> <xs:enumeration value="false"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="smallShop" default="false"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="true"/> <xs:enumeration value="false"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="guitar"> <xs:complexType> <xs:sequence> <xs:element ref="builder"/> <xs:element ref="model"/> <xs:element ref="back-sides"/> <xs:element ref="top"/> <xs:element ref="notes" minOccurs="0"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> </xs:complexType> </xs:element> <xs:element name="guitars"> <xs:complexType> <xs:sequence> <xs:element ref="guitar" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="model" type="xs:string"/> <xs:element name="notes" type="xs:string"/> <xs:element name="top"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="bearclaw" default="false"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="true"/> <xs:enumeration value="false"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>
1、新建一个名为jaxbDemo的项目;
2、将guitar.xsd文件及guitar.xml文件放至到项目的根目录下
3、下载xjc工具所需的JAXB2_20101209.jar包
http://jaxb.java.net/2.2.3/JAXB2_20101209.jar
4、双击jar包后生成一个jaxb-ri-20101209文件夹,然后将环境变量中Path变量设置为这个文件的bin目录的路径,这样xjc命令就可以使用了。
5、在命令模式下进入项目根目录,然后执行:
xjc -p test guitars.xsd -d src
命令这样所需的java类就生成了,以下为命令的详细说明:
xjc [–p java文件所在的包] [-xmlschema] [–d 保存java文件的目录]
-xmlschema xsd文件路径。
-d 指定了保存java文件的目录
-p 指定了生成的java文件所在的包
6、最后就可以写相应的xml2java和java2xml方法,对xml文件进行操作了代码如下Java2XML:
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import dto.Guitars;
/**
* 从guitars.xml读取信息,保存到java的类中,然后又写入另一个java文件中
*
* @author ming.chen
* @date 2011-2-25
* @version $Revision$
*/
public class Java2XML {
private String inputFilename;
private String outputFilename;
private JAXBContext jc;
private final String PACKAGE_NAME = "dto";
public Java2XML(String inputFilename, String outputFilename) throws Exception {
this.inputFilename = inputFilename;
this.outputFilename = outputFilename;
jc = JAXBContext.newInstance(PACKAGE_NAME);
}
public Guitars unmarshal() throws Exception {
Unmarshaller u = jc.createUnmarshaller();
return (Guitars) u.unmarshal(new FileInputStream(inputFilename));
}
public void marshal(Guitars guitars) throws Exception {
Marshaller m = jc.createMarshaller();
m.marshal(guitars, new FileOutputStream(outputFilename));
}
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Incorrect usage: java RoundTripper" + "[input XML filename] [output XML filename]");
return;
}
try {
Java2XML rt = new Java2XML(args[0], args[1]);
Guitars guitars = rt.unmarshal();
rt.marshal(guitars);
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
}
XML2Java.java
package test;
import java.io.FileInputStream;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import dto.Guitar;
import dto.Guitars;
/**
* 将guitars.xml的内容写入java内存
*
* @author ming.chen
* @date 2011-2-25
* @version $Revision$
*/
public class XML2Java {
private String inputFilename;
private JAXBContext jc;
private final String PACKAGE_NAME = "dto";
public XML2Java(String inputFilename) throws Exception {
this.inputFilename = inputFilename;
jc = JAXBContext.newInstance(PACKAGE_NAME);
}
public Guitars unmarshal() throws Exception {
Unmarshaller u = jc.createUnmarshaller();
return (Guitars) u.unmarshal(new FileInputStream(inputFilename));
}
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Incorrect usage: java RoundTripper" + "[input XML filename] [output XML filename]");
return;
}
try {
XML2Java rt = new XML2Java(args[0]);
Guitars guitars = rt.unmarshal();
List<Guitar> guitarList = guitars.getGuitar();
for (Guitar guitar : guitarList) {
System.out.println(guitar.getBackSides());
System.out.println(guitar.getId());
System.out.println(guitar.getNotes());
}
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
}