使用场景:最近做一个项目,项目中请求和相应报文均是xml格式的,然后报文头都是一样的,只是body会不同,JAXB是一个很好的解决java对象和xml的工具,我们需要在不用的接口返回不同的body体,但是又不想代码冗余每一个都写一个JAXB配置,最好是搞一个通用的,于是下面的代码就产生了。
一、简介
1、概念是什么:(Java Architecture for XML Binding) 是一个业界的标准,即是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。有多种实现。
2、JAXB中有什么:包含“xjc”工具和一个“schemagen”工具。
“xjc”工具可以用来将XML模式或其他类型模式文件(Java 1.6试验性地支持RELAX NG,DTD以及WSDL)转换为Java类。Java类使用javax.xml.bind.annotation包下的Java 标注,例如@XmlRootElement和@XmlElement。XML列表序列表示为java.util.List类型的属性, 通过JAXBContext可以创建Marshallers(将Java对象转换成XML)和Unmarshallers(将XML解析为Java对象)。
另外的“schemagen”工具,能够执行“xjc”的反向操作,通过一组标注的Java类创建一个XML模式。
二、依赖
JDK5以下开发需要的jar包:activation.jar、jaxb-api.jar、 jaxb-impl.jar、 jsr173-api.jar;
如果是基于JDK6以上版本已经集成JAXB2的JAR,在目录{JDK_HOME}/jre/lib/rt.jar中。
三、应用
第一步:创建要转化的java对象,该对象需要使用相关注解注释各字段
(标注在get方法上,标注在别的地方运行时会报错)
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
/**
*
* @author Zhaky
*/
@XmlRootElement(name = "merchant")
public class Merchant implements Serializable {
private CommonHead head;
private BaseBody body;
@XmlElement(name = "head")
public CommonHead getHead() {
return head;
}
public Merchant() {
super();
}
public void setHead(CommonHead head) {
this.head = head;
}
@XmlElements({//重要:
@XmlElement(name="body",type=Cancel.class),//这里的Cancel与下面类的@XmlType(name="Cancel")相对应,生成xml时节点名字为body
@XmlElement(name="body",type=Refund.class),
@XmlElement(name="body",type=Pay.class)
})
public BaseBody getBody() {
return body;
}
public void setBody(BaseBody body) {
this.body = body;
}
}
@XmlElements 重要说明:网上资料对这个参数介绍不多也不详细,简单来说就是通过这个参数实现按需加载实体
import javax.xml.bind.annotation.XmlTransient;
import java.io.Serializable;
/**
* Created by Zhaky
*/
@XmlTransient
public abstract class BaseBody implements Serializable {
public BaseBody() {
super();
}
}
//此处必须要有无参数的构造方法
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlType;
/**
*/
@XmlType(name="Cancel")
public class Cancel extends BaseBody {
//这里参数校验和xml实体公用了一个pojo
@NotNull(message = "{common.oriReqMsgId.not.empty}")
@Length(min = 0, max = 32, message = "{common.oriReqMsgId.length.error}")
private String oriReqMsgId;//原交易流水号
//扩展字段
@Length(min = 0, max = 128, message = "{common.extend1.length.error}")
private String extend1;//备用
@Length(min = 0, max = 128, message = "{common.extend2.length.error}")
private String extend2;//备用
@Length(min = 0, max = 128, message = "{common.extend3.length.error}")
private String extend3;//备用·
.....
//省略get set方法
}
配置完成开始使用!!
通用方法
public class XMLParaUtil{
public static String getRequestParamsXmlString(@Valid BaseBody requestVO) throws JAXBException {
Merchant message = new Merchant();
CommonHead head = new CommonHead();
head.init(DateFormatUtils.format(new Date(), "yyyyMMddHHmmss"));
message.setHead(head);
message.setBody(requestVO);
JAXBContext context = JAXBContext.newInstance(Merchant.class);
Marshaller marshaller = context.createMarshaller();
StringWriter sw = new StringWriter();
marshaller.marshal(message, sw);
return sw.toString();
}
}
外部使用时根据不同的场景引入不同的实现类即可
Cancel requestVO =new Cancel();
String plainXML = CmbcCore.getRequestParamsXmlString(requestVO);