现在的位置: 首页 > 综合 > 正文

JAXB技术实现java对象与xml相互转化

2014年07月14日 ⁄ 综合 ⁄ 共 7812字 ⁄ 字号 评论关闭

研究了两天技术,终于搞明白了两个技术及其区别,下面总结一下。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文件,同时控制台会输出相应的信息。

到这里就介绍完了,不懂的话再问我吧。

抱歉!评论已关闭.