一:JAXB注解
JAXB(Java API for XML Binding),提供了一个快速便捷的方式将Java对象与XML进行转换。JAXB 可以实现Java对象与XML的相互转换,在JAXB中,将一个Java对象转换为XML的过程称之为Marshal,将XML转换为Java对象的过程称之为UnMarshal。我们可以通过在 Java 类中标注注解的方式将一个Java对象绑定到一段XML,来说明java对象和XML元素的对应关系。
@XmlRootElement 将一个Java类映射为一段XML的根节点
参数: name 定义这个根节点的名称
namespace 定义这个根节点命名空间
@XmlAccessorType 定义映射这个类中的何种类型需要映射到XML。可接收四个参数,分别是:
参数: XmlAccessType.FIELD: 映射这个类中的所有字段到XML
XmlAccessType.PROPERTY: 映射这个类中的属性(get/set方法)到XML
XmlAccessType.PUBLIC_MEMBER: 将这个类中的所有public的field或property同时映射到XML(默认)
XmlAccessType.NONE: 不映射
@XmlElement 指定一个字段或get/set方法映射到XML的节点。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一个没有get/set方法的字段上标注此注解,即可将该字段映射到XML。
参数: defaultValue 指定节点默认值
name 指定节点名称
namespace 指定节点命名空间
required 是否必须(默认为false)
nillable 该字段是否包含 nillable="true" 属性(默认为false)
type 定义该字段或属性的关联类型
@XmlAttribute 指定一个字段或get/set方法映射到XML的属性。
参数: name 指定属性名称
namespace 指定属性命名空间
required 是否必须(默认为false)
<strong>@XmlTransient</strong> 定义某一字段或属性不需要被映射为XML。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一get/set方法的字段上标注此注解,那么该属性则不会被映射。
@XmlType 定义映射的一些相关规则
参数: propOrder 指定映射XML时的节点顺序
factoryClass 指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身
factoryMethod 指定工厂类的工厂方法
name 定义XML Schema中type的名称
namespace 指定Schema中的命名空间
@XmlElementWrapper 为数组元素或集合元素定义一个父节点。如,类中有一元素为List items,若不加此注解,该元素将被映射为
<items>...</items>
<items>...</items>
这种形式,此注解可将这个元素进行包装,如:
@XmlElementWrapper(name="items")
@XmlElement(name="item")
public List items;
将会生成这样的XML样式:
<items>
<item>...</item>
<item>...</item>
</items>
@XmlJavaTypeAdapter 自定义某一字段或属性映射到XML的适配器。如,类中包含一个接口,我们可以定义一个适配器(继承自 javax.xml.bind.annotation.adapters.XmlAdapter类),指定这个接口如何映射到XML。
@XmlSchema 配置整个包的namespace,这个注解需放在package-info.java文件中。
二:实例
定义context类,其中包含Datesource和一个NewWs组成的set
package jaxb;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
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;
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Context", propOrder = { "datasource", "newsWs" })
@XmlRootElement(name = "context")
public class Context {
@XmlElement(name = "datasource")
private Datasource datasource;
@XmlElementWrapper(name = "news-ws-define")
@XmlElement(name = "news-ws")
private Set<NewsWs> newsWs;
public Context() {
super();
}
public Context(Datasource datasource, Set<NewsWs> newsWs) {
super();
this.datasource = datasource;
this.newsWs = newsWs;
}
public Datasource getDatasource() {
return datasource;
}
public void setDatasource(Datasource datasource) {
this.datasource = datasource;
}
public Set<NewsWs> getNewsWs() {
return newsWs;
}
public void setNewsWs(Set<NewsWs> newsWs) {
this.newsWs = newsWs;
}
@Override
public String toString() {
return "Conext [datasource=" + datasource + ", newsWs=" + newsWs + "]";
}
}
分别定义Datesource类和NewWs类
package jaxb;
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "dbtype", "url", "user", "password" })
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "datasource")
public class Datasource {
@XmlElement(name = "db-type")
private String dbtype;
@XmlElement(name = "url")
private String url;
@XmlElement(name = "user")
private String user;
@XmlElement(name = "password")
private String password;
public Datasource() {
super();
}
public Datasource(String dbtype, String url, String user, String password) {
super();
this.dbtype = dbtype;
this.url = url;
this.user = user;
this.password = password;
}
public String getDbtype() {
return dbtype;
}
public void setDbtype(String dbtype) {
this.dbtype = dbtype;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Datasource [dbtype=" + dbtype + ", url=" + url + ", user=" + user + ", password=" + password + "]";
}
}
package jaxb;
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "sql", "time", "column", "allyCode" })
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "news-ws")
public class NewsWs {
@XmlElement(name = "sql")
private String sql;
@XmlElement(name = "time")
private String time;
@XmlElement(name = "column")
private String column;
@XmlElement(name = "ally-code")
private String allyCode;
public NewsWs() {
super();
}
public NewsWs(String sql, String time, String column, String allyCode) {
super();
this.sql = sql;
this.time = time;
this.column = column;
this.allyCode = allyCode;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getColumn() {
return column;
}
public void setColumn(String column) {
this.column = column;
}
public String getAllyCode() {
return allyCode;
}
public void setAllyCode(String allyCode) {
this.allyCode = allyCode;
}
@Override
public String toString() {
return "NewsWs [sql=" + sql + ", time=" + time + ", column=" + column + ", allyCode=" + allyCode + "]";
}
}
实现一个JAXBUtil工具类
package jaxb.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class JAXBUtil {
private static final String ENCODING = "UTF-8";
private static final Log logger = LogFactory.getLog(JAXBUtil.class);
public static <T> T formXML(Class<T> clazz, String xml) {
JAXBContext jaxbContext = null;
T object = null;
if (xml != null && !"".equals(xml)) {
try {
jaxbContext = JAXBContext.newInstance(clazz);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xml.getBytes(ENCODING));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<T> jaxbElement = unmarshaller.unmarshal(new StreamSource(byteArrayInputStream), clazz);
object = (T) jaxbElement.getValue();
} catch (Exception e) {
logger.error("error when unmarshalling from a xml string");
}
}
return object;
}
public static <T> String toXML(T object) {
String xml = "";
try {
JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
Marshaller marshaller = jaxbContext.createMarshaller();
// 是否格式化生成xml
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 设置编码方式
marshaller.setProperty(Marshaller.JAXB_ENCODING, ENCODING);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
marshaller.marshal(object, byteArrayOutputStream);
byte[] buf = byteArrayOutputStream.toByteArray();
xml = new String(buf, 0, buf.length, ENCODING);
} catch (Exception e) {
logger.error("error when marshalling to a xml string");
}
return xml;
}
}
测试函数:
package jaxb;
import java.util.HashSet;
import java.util.Set;
import jaxb.util.JAXBUtil;
public class JaxbTest {
public static void main(String[] args) throws Exception {
Set<NewsWs> set = new HashSet<NewsWs>();
Datasource datasource = new Datasource("Mysql", "http://127.0.0.1:8080/hello", "root", "123");
NewsWs newsWs1 = new NewsWs("sql1", "2013年7月13日", "新闻内容1", "验证1");
NewsWs newsWs2 = new NewsWs("sql2", "2013年7月14日", "新闻内容2", "");
NewsWs newsWs3 = new NewsWs("sql3", "2013年7月15日", "新闻内容3", "验证1");
set.add(newsWs1);
set.add(newsWs2);
set.add(newsWs3);
Context context = new Context(datasource, set);
String xml = JAXBUtil.toXML(context);
System.out.println(xml);
Context context1 = JAXBUtil.formXML(Context.class , xml);
System.out.println(context1.getDatasource().toString());
Set<NewsWs> set1 = context1.getNewsWs();
for (NewsWs ws : set1) {
System.out.println("**************");
System.out.println(ws.getSql());
System.out.println(ws.getTime());
System.out.println(ws.getColumn());
System.out.println(ws.getAllyCode());
}
}
}
运行结果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<context>
<datasource>
<db-type>Mysql</db-type>
<url>http://127.0.0.1:8080/hello</url>
<user>root</user>
<password>123</password>
</datasource>
<news-ws-define>
<news-ws>
<sql>sql2</sql>
<time>2013年7月14日</time>
<column>新闻内容2</column>
<ally-code></ally-code>
</news-ws>
<news-ws>
<sql>sql1</sql>
<time>2013年7月13日</time>
<column>新闻内容1</column>
<ally-code>验证1</ally-code>
</news-ws>
<news-ws>
<sql>sql3</sql>
<time>2013年7月15日</time>
<column>新闻内容3</column>
<ally-code>验证1</ally-code>
</news-ws>
</news-ws-define>
</context>
Datasource [dbtype=Mysql, url=http://127.0.0.1:8080/hello, user=root, password=123]
**************
sql3
2013年7月15日
新闻内容3
验证1
**************
sql2
2013年7月14日
新闻内容2
**************
sql1
2013年7月13日
新闻内容1
验证1