您的位置:首页 > 编程语言 > Java开发

eclipseLink基于JAXB方式实现javabean与xml的互转

2015-12-25 00:00 399 查看
摘要: jdk1.6版本中直接添加了JAXB的功能,使用注解的方式快速的实现javabean与xml的互转

项目中经常需要遇到使用xml方式传输数据,这样就无可避免的要说到xml的框架。就我个人使用的主要有dom4j、xstream。以个人观点来看,dom4j写xml文件较繁琐,但是查询结合xpath时十分便捷;xstream十分小巧方便,但在做节点的属性时需要费点周折,比如<name id="aaa1">张三</name>,对于这种需要另外定义一个converter。

JAXB在我看来兼顾了dom4j的查询便捷、xstream的写xml的方便。不过我说的是基于eclipselink的MOXy实现的,它实现了基于xpath的方式写入和解析xml文件。eclipselink的MOXy添加了@XmlPath的注解,将xml的节点或属性与javabean的属性做一对一的映射。对集合类型的支持也十分友好。

例如xml结构如下

<?xml version="1.0" encoding="GBK"?>
<SONRS>
<STATUS ID="AAA">
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>2015-12-24 13:56:23</DTSERVER>
<LIST>
<USER>
<NAME>张三</NAME>
</USER>
<USER>
<NAME>李四</NAME>
</USER>
</LIST>
</SONRS>

定义一个操作员的登录信息校验的VO,

package com.test.xmlCnvtr;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

/**
* 操作员登录验证响应
* @author wade
*
*/
@XmlRootElement(name = "SONRS")
@XmlAccessorType(XmlAccessType.FIELD)
public class SonRs {
@XmlPath("/STATUS/@ID")
private String ID;//ID号

private String DTSERVER;//客户端日期时间

@XmlPath("/STATUS/CODE/text()")
private String CODE;//处理结果码

@XmlPath("/STATUS/SEVERITY/text()")
private String SEVERITY;//处理结果等级

@XmlPath("/STATUS/MESSAGE/text()")
private String MESSAGE;//消息描述

@XmlPath("/LIST/USER")
private List<User> list;//人员信息列表

public List<User> getList(){
return list;
}

public void setList(List<User> list){
this.list = list;
}

public String getID(){
return ID;
}

public void setID(String iD){
ID = iD;
}

public String getMESSAGE() {
return MESSAGE;
}

public void setMESSAGE(String mESSAGE) {
MESSAGE = mESSAGE;
}

public String getDTSERVER() {
return DTSERVER;
}

public void setDTSERVER(String dTSERVER) {
DTSERVER = dTSERVER;
}

public String getCODE() {
return CODE;
}

public void setCODE(String cODE) {
CODE = cODE;
}

public String getSEVERITY() {
return SEVERITY;
}

public void setSEVERITY(String sEVERITY) {
SEVERITY = sEVERITY;
}

}

List列表中的用户信息vo

package com.test.xmlCnvtr;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

/**
* 操作员登录验证响应
* @author wade
*
*/
@XmlRootElement(name = "USER")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
@XmlPath("/NAME/text()")
private String NAME;//名称

public void setNAME(String name){
this.NAME = name;
}

public String getNAME(){
return NAME;
}
}

package com.test.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* MOXy jaxb工具类,用于xml与javabean的相互装换
* @author wade
*
*/
public class MOXyJaxbUtil {

private static final Log logger = LogFactory.getLog(MOXyJaxbUtil.class);

/**
* JavaBean转换成xml
* 默认编码UTF-8
* @param obj
* @param writer
* @return
* @throws JAXBException
*/
public static String convertToXml(Object obj) throws JAXBException {
return convertToXml(obj, "GBK");
}

/**
* JavaBean转换成xml
* @param obj
* @param encoding
* @return
* @throws JAXBException
*/
public static String convertToXml(Object obj, String encoding) throws JAXBException {
String result = null;

JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
result = writer.toString();

return result;
}

/**
* xml转换成JavaBean
* @param inputStream
* @param c
* @return
* @throws JAXBException
*/
@SuppressWarnings("unchecked")
public static <T> T converyToJavaBean(InputStream inputStream, Class<T> c) throws JAXBException {
T t = null;
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(inputStream);
return t;
}
/**
* xml转换成JavaBean
* @param str xml
* @param c
* @return
* @throws JAXBException
*/
public static <T> T converyToJavaBean(String str, Class<T> c) throws JAXBException {
return converyToJavaBean(new ByteArrayInputStream(str.getBytes()),c);
}

}

有一个问题需要注意,在实施过程中,发现部分项目返回的xml只有数据体,没有包含

<?xml version="1.0" encoding="GBK"?>

在实际的解析过程中,因为我的JVM默认走的是UTF-8,而对方返回的xml是GBK的,所以导致解析出错。jaxb utf-8 unmarshal exception invalid byte 1of 2 byte utf-8 sequence。此时在返回的数据体上添加xml格式头即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  eclipselink MOXy jaxb xpath