jaxb实现xml与bean的相互转化
jaxb使用完整例子
这里边有提到 MessageFormat,可以了解下。下边还有一个其他博客粘过来的几行代码,记录一下。
附上几个链接 [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换 JAXB生成CDATA类型的节点 Jaxb如何优雅的处理CData
我这里以《书》为例,写一个完整的测试代码,xml包含了各种元素和集合。
test.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <book id="1234567890" name="寻医不如自医"> <author>陈金柱</author> <press>金城出版社</press> <main_info> <chapters_num>5</chapters_num> <editor>王景涛</editor> <pub_time>2017-01-01</pub_time> </main_info> <chapters> <chapter> <num>1</num> <name>你所不知道的事</name> </chapter> <chapter> <num>2</num> <name>人体中有哪些重要的部分</name> </chapter> <chapter> <num>3</num> <name>中医健康基础知识</name> </chapter> </chapters> </book>
实体类:
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* 书
* 不指定顺序的时候是按英文字母排序的
* propOrder指定顺序,里边填的是属性的名,不是注解里的name
* 如果指定顺序的话,需要把所有属性都写里边,不然会报错
* @author changxinzhi
*
*/
@XmlRootElement(name = "book")
@XmlType(propOrder={"id","name","author","press","mainInfo","chapters"})
public class Book {
private String id;//图书ID
private String name;//图书名称
private String author;//作者
private String press;//出版社
private MainInfo mainInfo;//重要信息
private List<Chapter> chapters;//章节信息
@XmlAttribute(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlAttribute(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement(name = "author")
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@XmlElement(name = "press")
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
@XmlElement(name = "main_info")
public MainInfo getMainInfo() {
return mainInfo;
}
public void setMainInfo(MainInfo mainInfo) {
this.mainInfo = mainInfo;
}
@XmlElementWrapper(name = "chapters")
@XmlElement(name = "chapter")
public List<Chapter> getChapters() {
return chapters;
}
public void setChapters(List<Chapter> chapters) {
this.chapters = chapters;
}
}
import javax.xml.bind.annotation.XmlRootElement;
/**
* 书的重要信息
* @author cxz
*/
@XmlRootElement(name = "main_info")
public class MainInfo {
private String editor;//责任编辑
private String pub_time;
private String chapters_num;
public String getEditor() {
return editor;
}
public void setEditor(String editor) {
this.editor = editor;
}
public String getPub_time() {
return pub_time;
}
public void setPub_time(String pub_time) {
this.pub_time = pub_time;
}
public String getChapters_num() {
return chapters_num;
}
public void setChapters_num(String chapters_num) {
this.chapters_num = chapters_num;
}
}
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* 章节信息
* @author cxz
*/
@XmlRootElement(name="chapter")
@XmlType(propOrder={"num","name"})
public class Chapter {
private String num;
private String name;
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
工具类
import java.io.StringReader;
import java.io.StringWriter;
import java.text.MessageFormat;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
/**
* json使用alibaba.fastjson
* @author cxz
* Jaxb2.0 处理Xml与Object转换
*/
public class JaxbObjectAndXmlUtil {
/**
* 此处使用了Stringreader,其实Unmarshaller接口还支持
* File,InputStream,URL,StringBuffer,org.w3c.dom.Node等反序列化
* API连接
* http://tool.oschina.net/uploads/apidocs/jdk-zh/javax/xml/bind/Unmarshaller.html
* @param xmlStr 字符串
* @param c 对象Class类型
* @return 对象实例
*/
@SuppressWarnings({ "unchecked", "finally" })
public static <T> T xml2Object(String xmlStr,Class<T> c){
try{
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
T t = (T) unmarshaller.unmarshal(new StringReader(xmlStr));
return t;
} catch (JAXBException e) {
e.printStackTrace(); return null;
}
}
/**
* 可变参数
* config里使用占位符 {0} {1} {2},单引号要使用两个
* MessageFormat使用链接
* @param config
* @param c
* @param arguments
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T xml2Object(String config,Class<T> c,Object... arguments){
try{
if (arguments.length > 0) {
config = MessageFormat.format(config, arguments);
}
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
T t = (T) unmarshaller.unmarshal(new StringReader(config));
return t;
} catch (JAXBException e) {
e.printStackTrace(); return null;
}
}
/**
* @param object 对象
* @return 返回xmlStr
*/
public static String object2Xml(Object object){
try{
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(object.getClass());
Marshaller marshal = context.createMarshaller();
marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化输出
marshal.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// 编码格式,默认为utf-8
marshal.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xml头信息 否
//不进行转移字符的处理
// marshal.setProperty(
// "com.sun.xml.bind.marshaller.CharacterEscapeHandler",
// new CharacterEscapeHandler() {
// @Override
// public void escape(char[] ch, int start, int length,
// boolean isAttVal, Writer writer) throws IOException {
// writer.write(ch, start, length);
// }
// });
marshal.setProperty("jaxb.encoding", "utf-8");
marshal.marshal(object,writer);
return new String(writer.getBuffer());
}catch(Exception e){
e.printStackTrace(); return null;
}
}
}
测试类
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
public class test {
/**
* 测试方法
* @param args
*/
public static void main(String[] args){
//创建内容
MainInfo mainInfo = new MainInfo();
mainInfo.setEditor("王景涛");
mainInfo.setPub_time("2017-01-01");
mainInfo.setChapters_num("5");
Chapter chapter1 = new Chapter();
chapter1.setNum("1");
chapter1.setName("你所不知道的事");
Chapter chapter2 = new Chapter();
chapter2.setNum("2");
chapter2.setName("人体中有哪些重要的部分");
Chapter chapter3 = new Chapter();
chapter3.setNum("3");
chapter3.setName("中医健康基础知识");
Book book = new Book();
List<Chapter> chapters = new ArrayList<Chapter>();
chapters.add(chapter1);
chapters.add(chapter2);
chapters.add(chapter3);
book.setChapters(chapters);
book.setMainInfo(mainInfo);
book.setId("1234567890");
book.setName("寻医不如自医");
book.setAuthor("陈金柱");
book.setPress("金城出版社");
String xmlStr = JaxbObjectAndXmlUtil.object2Xml(book);//构造报文 XML 格式的字符串
System.out.println("对象转xml报文: \n"+xmlStr);
Book book2 = JaxbObjectAndXmlUtil.xml2Object(xmlStr, Book.class);
System.out.println("报文转xml转: \n"+JSON.toJSONString(book2));
}
}
到这里已写完。
粘过来的几行代码,欢迎留言讨论。
import java.io.StringReader; import java.io.StringWriter; import java.util.Collection; 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; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.namespace.QName; import org.apache.commons.lang.StringUtils; /** * 使用Jaxb2.0实现XML<->Java Object的Binder. * StringUtils依赖commons-long包 * 特别支持Root对象是List的情形.---??? ‘xml规范就是有且只有一个根元素’--不甚理解这里的做法 * @author */ public class JaxbUtil { // 多线程安全的Context. private JAXBContext jaxbContext; /** * @param types 所有需要序列化的Root对象的类型. */ public JaxbUtil(Class<?>... types) { try { jaxbContext = JAXBContext.newInstance(types); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Java Object->Xml. */ public String toXml(Object root, String encoding) { try { StringWriter writer = new StringWriter(); createMarshaller(encoding).marshal(root, writer); return writer.toString(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Java Object->Xml, 特别支持对Root Element是Collection的情形. */ @SuppressWarnings("unchecked") public String toXml(Collection root, String rootName, String encoding) { try { CollectionWrapper wrapper = new CollectionWrapper(); wrapper.collection = root; JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>( new QName(rootName), CollectionWrapper.class, wrapper); StringWriter writer = new StringWriter(); createMarshaller(encoding).marshal(wrapperElement, writer); return writer.toString(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Xml->Java Object. */ @SuppressWarnings("unchecked") public <T> T fromXml(String xml) { try { StringReader reader = new StringReader(xml); return (T) createUnmarshaller().unmarshal(reader); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Xml->Java Object, 支持大小写敏感或不敏感. */ @SuppressWarnings("unchecked") public <T> T fromXml(String xml, boolean caseSensitive) { try { String fromXml = xml; if (!caseSensitive) fromXml = xml.toLowerCase(); StringReader reader = new StringReader(fromXml); return (T) createUnmarshaller().unmarshal(reader); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * 创建Marshaller, 设定encoding(可为Null). */ public Marshaller createMarshaller(String encoding) { try { Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); if (StringUtils.isNotBlank(encoding)) { marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); } return marshaller; } catch (JAXBException e) { throw new RuntimeException(e); } } /** * 创建UnMarshaller. */ public Unmarshaller createUnmarshaller() { try { return jaxbContext.createUnmarshaller(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * 封装Root Element 是 Collection的情况.
* xmlAnyType查到的东西不多,不太懂这个。 */ public static class CollectionWrapper { @SuppressWarnings("unchecked") @XmlAnyElement protected Collection collection; } }
测试方法片段
//写不写CollectionWrapper.class有什么区别,都可以正常运行 //将java对象转换为XML字符串 JaxbUtil requestBinder = new JaxbUtil(Hotel.class,CollectionWrapper.class); String retXml = requestBinder.toXml(hotel, "utf-8"); System.out.println("xml:"+retXml); //将xml字符串转换为java对象 JaxbUtil resultBinder = new JaxbUtil(Hotel.class,CollectionWrapper.class); Hotel hotelObj = resultBinder.fromXml(retXml);