研究了两天技术,终于搞明白了两个技术及其区别,下面总结一下。XStream和JAXB都可以完成java对象与xml相互转化,但是差别巨大。本文介绍一下JAXB。
使用JAXB需要满足的条件:
1、一个格式良好的schema文档,格式错误的话,下面没有办法执行了。
2、安装好jdk1.6或以上的版本。低版本的jdk比较麻烦,这里不做介绍了。
3、差不多够了,最好安装的有myeclipse或者eclipse。
下面是一份schema文档,名称:messages.xsd
view plaincopy to clipboardprint?
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="catalog" type="catalogType"/>
<xsd:complexType name="catalogType">
<xsd:sequence>
<xsd:element ref="journal" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="section" type="xsd:string"/>
<xsd:attribute name="publisher" type="xsd:string"/>
</xsd:complexType>
<xsd:element name="journal" type="journalType"/>
<xsd:complexType name="journalType">
<xsd:sequence>
<xsd:element ref="article" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="article" type="articleType"/>
<xsd:complexType name="articleType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="level" type="xsd:string"/>
<xsd:attribute name="date" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="catalog" type="catalogType"/>
<xsd:complexType name="catalogType">
<xsd:sequence>
<xsd:element ref="journal" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="section" type="xsd:string"/>
<xsd:attribute name="publisher" type="xsd:string"/>
</xsd:complexType>
<xsd:element name="journal" type="journalType"/>
<xsd:complexType name="journalType">
<xsd:sequence>
<xsd:element ref="article" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="article" type="articleType"/>
<xsd:complexType name="articleType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="level" type="xsd:string"/>
<xsd:attribute name="date" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
把该文档放入d盘下,新建一个src目录,schema文件和src目录平级,点击运行->cmd->dos窗口,输入如下命令:
xjc -p com.techcenter.jaxb messages.xsd -d src
在src目录下会生成四个java文件,把这些类复制到你的myeclipse的工作空间下。
命令的含义:xjc是jdk里面的一个可以执行的exe文件,-p后面的内容是生成的文件放到哪个包下,messages.xsd是schema文件的名称,-d后面的内容是生成的文件放到哪个目录下。这里是同一目录,所以命令比较简单。如果不在同一目录,命令就比较复杂了,要写绝对路径。
xjc -d "F:\SVN\ihandy_standardsm_app\ihandy_fullgoal_fundbill\src\main\java" -p "com.techcenter.fullgoal.fundbill" "F:\无线天利常用\富国基金账单\data(2).xsd"
现在具备了基本的对象类,下面开始实现转化工作。
绑定对象到xml的工具类,绑定xml到对象的工具类CatalogTypeUtils
view plaincopy to clipboardprint?
package com.techcenter.jaxb;
import java.io.*;
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;
/**
* 绑定对象到xml的工具类,绑定xml到对象的工具类
* @author xiaojunwei
* @2010-11-23 @下午06:19:37
*/
public class CatalogTypeUtils {
private static JAXBContext jaxbContext = null;
private static Marshaller marshaller = null;
private static ObjectFactory factory = null;
/**
* 绑定对象到xml文件
* @param catalogType 对象
* @param xmlDocument xml文档
*/
public static void buildXml(CatalogType catalogType, File xmlDocument) {
try {
//获得 JAXBContext 类的新实例。它使用当前线程的上下文类加载器
jaxbContext = JAXBContext.newInstance("com.techcenter.jaxb");
//创建一个可以用来将 java 内容树转换为 XML 数据的 Marshaller 对象。
marshaller = jaxbContext.createMarshaller();
//此类表示用于创建对象的工厂。
factory = new ObjectFactory();
//返回 xml 元素声明的类型属性的 Java 绑定。
JAXBElement<CatalogType> catalogElement = factory.createCatalog(catalogType);
if(xmlDocument != null && xmlDocument.exists()){
OutputStream out= new FileOutputStream(xmlDocument);
//将以 jaxbElement 为根的内容树编组到输出流中。
marshaller.marshal(catalogElement, out);
out.close();
}else{
return ;
}
}catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 绑定xml到对象
* @param file xml文件
* @return
*/
@SuppressWarnings("unchecked")
public static CatalogType buildObject(File file) {
//Xml 元素的 JAXB 表示形式。
JAXBElement<CatalogType> catalogElement = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance("com.techcenter.jaxb");
//创建一个可以用来将 XML 数据转换为 java 内容树的 Unmarshaller 对象。
Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
//InputStream in = new FileInputStream(file);
// 从指定的文件解组 XML 数据并返回得到的内容树。
catalogElement = (JAXBElement<CatalogType>) unMarshaller.unmarshal(file);
} catch (Exception e) {
e.printStackTrace();
}
return catalogElement.getValue();
}
}
测试类:JaxbDemo
package com.techcenter.jaxb;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
/**
* 测试类
* @author xiaojunwei
* @2010-11-23 @下午06:23:25
*/
public class JaxbDemo {
static final Logger logger = LoggerFactory.getLogger(JaxbDemo.class);
//构建工厂
private ObjectFactory factory = new ObjectFactory();
/**
* @param xmlDocument is the output xml file
* 测试输出xml文件
*/
public void testObject2Xml(File xmlDocument) {
//用工厂创建对象
CatalogType catalog = factory.createCatalogType();
//
assmbleCatalogForTest(catalog);
//调用绑定对象到xml
CatalogTypeUtils.buildXml(catalog, xmlDocument);
}
/**
* @param xmlDocument is the source xml file for generating Object
* 测试xml文件到对象
*/
public CatalogType testXml2Object(File file) {
return CatalogTypeUtils.buildObject(file);
}
/**
* This function is used to assmble CatalogType object for test
* 向对象中赋值,封装对象
*/
private CatalogType assmbleCatalogForTest(CatalogType catalog) {
//向CatalogType中set两个值
catalog.setSection("Java Technology");
catalog.setPublisher("IBM developerWorks");
//创建JournalType对象
JournalType journal = factory.createJournalType();
//创建ArticleType对象
ArticleType article = factory.createArticleType();
//向ArticleType中赋值
article.setLevel("Intermediate");
article.setDate("January-2004");
article.setTitle("Service Oriented Architecture Frameworks");
article.setAuthor("Naveen Balani");
//得到JournalType集合,集合中没有内容
java.util.List<JournalType> journalList = catalog.getJournal();
//向集合中添加数据
journalList.add(journal);
//同上
java.util.List<ArticleType> articleList = journal.getArticle();
articleList.add(article);
//再创建一个ArticleType对象,向ArticleType中赋值
article = factory.createArticleType();
article.setLevel("Advanced");
article.setDate("October-2003");
article.setTitle("Advance DAO Programming");
article.setAuthor("Sean Sullivan");
articleList = journal.getArticle();
articleList.add(article);
//再创建一个ArticleType对象,向ArticleType中赋值
article = factory.createArticleType();
article.setLevel("Advanced");
article.setDate("May-2002");
article.setTitle("Best Practices in EJB Exception Handling");
article.setAuthor("Srikanth Shenoy");
articleList = journal.getArticle();
articleList.add(article);
//返回CatalogType
return catalog;
}
/**
* 加载日志的静态块,采用logback输出日志
*/
static{
String logbackCfg = "./conf/logback.xml";
try {
// 初始化log配置
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
configurator.doConfigure(logbackCfg);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] arg) {
JaxbDemo test = new JaxbDemo();
test.testObject2Xml(new File("d:\\hello.xml"));
CatalogType type = test.testXml2Object(new File("d:\\hello.xml"));
logger.info("publisher={},section={}",type.getPublisher(),type.getSection());
List<JournalType> list = type.getJournal();
for(JournalType journalType: list){
for (Iterator<ArticleType> it = journalType.getArticle().iterator();it.hasNext();){
ArticleType articleType = it.next();
logger.info("title={},author={},level={},date={}",
new String[]{articleType.getTitle(),articleType.getAuthor(),
articleType.getLevel(),articleType.getDate()});
}
}
}
}
把刚才的那两个类也复制到你的工作空间下。
启动程序。应该会生成hello.xml文件,同时控制台会输出相应的信息。
到这里就介绍完了,不懂的话再问我吧。