JAXB2.0使用
以前实习的时候用过JAXB1.x,据说JAXB2.0使用了Java 5.0的新特性,例如注解、泛型,使得JAXB更容易使用,于是从
网上下来试了一下:
从https://jaxb.dev.java.net/servlets/ProjectDocumentList?folderID=6344&expandFolder=6344&folderID=0
下载到JAXB2_20061115.jar,为了方便使用把JAXB2_20061115.jar拷到工程中,本事例使用Eclipse开发,工程目录
为:D:/eclipse/workspace/JaxbTest,可以新建一个目录jaxb来存放JAXB2_20061115.jar,在命令行下,把目录切换
到jaxb下(当然开始要配置好环境变量),使用java -jar JAXB2_20061115.jar生成一个目录:jaxb-ri-20061115,里面
有bin和lib,在bin目录下新建一个generator.bat的批处理:
xjc -d D:/eclipse/workspace/JaxbTest/src -p "edu.jlu.xml" "D:/eclipse/workspace/JaxbTest/schema/messages.xsd"
其中D:/eclipse/workspace/JaxbTest/src为原文件的目录,edu.jlu.xml为生成Java类的包名,D:/eclipse/workspace/JaxbTest/schema/messages.xsd为xml schema文件的路径。
这样以后我们每次修改messages.xsd,我们只需要双击generator.bat来更新Java类就可以了。
下面我们我们在messages.xsd定义schema:
< 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 >
然后双击generator.bat就可以生成Java类了,本例我们生成了ArticleType.java,CatalogType.java,
JournalType.java和ObjectFactory.java
一般我们会对XML根的那个element对应的Java类,写一个实用的xml与object之间转换的类,本例中
为那个element为catalog,对应的Java类为CatalogType.java,我们可以写一个CatalogTypeUtils来帮助
我们实现xml与object之间的转换:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
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;
public class CatalogTypeUtils ... {
private static JAXBContext jaxbContext = null;
private static Marshaller marshaller = null;
private static ObjectFactory factory = null;
/**//*
*@param catalogType is the object that is used to build xml
*@param xmlDocument is the file where xml to output
*/
public static void buildXml(CatalogType catalogType, File xmlDocument) ...{
try ...{
jaxbContext = JAXBContext.newInstance("edu.jlu.xml");
marshaller = jaxbContext.createMarshaller();
ObjectFactory factory = new ObjectFactory();
JAXBElement<CatalogType> catalogElement = factory.createCatalog(catalogType);
marshaller.marshal(catalogElement,new FileOutputStream(xmlDocument));
} catch (FileNotFoundException e) ...{
e.printStackTrace();
} catch (JAXBException e) ...{
e.printStackTrace();
}
}
/**//*
*@param xmlDocument the xml file to build object
*@return the built object
*/
public static CatalogType buildObject(File xmlDocument) ...{
JAXBElement<CatalogType> catalogElement = null;
try ...{
JAXBContext jaxbContext = JAXBContext.newInstance("edu.jlu.xml");
Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
catalogElement = (JAXBElement<CatalogType>) unMarshaller.unmarshal(xmlDocument);
} catch (Exception e) ...{
e.printStackTrace();
}
return catalogElement.getValue();
}
}
下面我们做一下测试:
import java.io.File;
import edu.jlu.xml.ArticleType;
import edu.jlu.xml.CatalogType;
import edu.jlu.xml.CatalogTypeUtils;
import edu.jlu.xml.JournalType;
import edu.jlu.xml.ObjectFactory;
public class Test ... {
private ObjectFactory factory = new ObjectFactory();
/**//*
* @param xmlDocument is the output xml file
*/
public void testObject2Xml(File xmlDocument) ...{
CatalogType catalog = factory.createCatalogType();
assmbleCatalogForTest(catalog);
CatalogTypeUtils.buildXml(catalog,xmlDocument);
}
/**//*
* @param xmlDocument is the source xml file for generating Object
*/
public CatalogType testXml2Object(File xmlDocument)...{
return CatalogTypeUtils.buildObject(xmlDocument);
}
/**//*
* This function is used to assmble CatalogType object for test
*/
private CatalogType assmbleCatalogForTest(CatalogType catalog)...{
catalog.setSection("Java Technology");
catalog.setPublisher("IBM developerWorks");
JournalType journal = factory.createJournalType();
ArticleType article = factory.createArticleType();
article.setLevel("Intermediate");
article.setDate("January-2004");
article.setTitle("Service Oriented Architecture Frameworks");
article.setAuthor("Naveen Balani");
java.util.List journalList = catalog.getJournal();
journalList.add(journal);
java.util.List articleList = journal.getArticle();
articleList.add(article);
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);
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);
return catalog;
}
public static void main(String[] argv) ...{
Test test = new Test();
test.testObject2Xml(new File("E:/hello.xml"));
CatalogType type = test.testXml2Object(new File("E:/hello.xml"));
System.out.println(type.getPublisher());
}
}
实现类,其实生成的Object分离出接口的意义并不大,JAXB2.0直接生成一个type具体的class,
并且代码比以前更易读了)