package com.mcp.util;
import org.apache.commons.lang3.StringUtils;
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;
/**
* Created by shiqm on 2016-05-01.
*/
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_ENCODING, "UTF-8");// //编码格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);// 是否格式化生成的xml串
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);// 是否省略xm头声明信息
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的情况.
*/
public static class CollectionWrapper {
@SuppressWarnings("unchecked")
@XmlAnyElement
protected Collection collection;
}
}
/**
* Created by shiqm on 2016-04-29.
*/
public class XmlUtil {
public static String toXML(Object obj) {
try {
JaxbUtil requestBinder = new JaxbUtil(obj.getClass());
return requestBinder.toXml(obj, "utf-8");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public static <T> T fromXML(String xml, Class<T> valueType) {
try {
JaxbUtil requestBinder = new JaxbUtil(valueType);
return (T) requestBinder.fromXml(xml);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}
Demo
这里以一个继承来展示,里边包含了普通熟悉和集合的转化,当然更可以不用继承。这里默认get和set方法来组织xml,没有方法的属性使用注解来组织xml。当然还可以不默认get和set方法,用@XmlAccessorType(XmlAccessType.FIELD)
package com.mcp.bean.yeepay;
import com.mcp.cons.YeePayConstants;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
/**
* Created by shiqm on 2016-04-29.
*/
public class Request {
@XmlAttribute
protected String platformNo = YeePayConstants.Config.MER_CODE;
@XmlElement
protected String notifyUrl = YeePayConstants.NOTITY_Url;
@XmlElement
protected String callbackUrl = YeePayConstants.CALLBACK_URL;
private String platformUserNo;
private String requestNo;
public String getPlatformUserNo() {
return platformUserNo;
}
public void setPlatformUserNo(String platformUserNo) {
this.platformUserNo = platformUserNo;
}
public String getRequestNo() {
return requestNo;
}
public void setRequestNo(String requestNo) {
this.requestNo = requestNo;
}
}
package com.mcp.bean.yeepay;
import javax.xml.bind.annotation.*;
import java.util.List;
/**
* Created by shiqm on 2016-05-01.
*/
@XmlRootElement(name = "request")
public class CpTransactionParam extends Request {
private String userType;
private String bizType;
private List<Property> properties;
private List<Detail> details;
public CpTransactionParam() {
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getBizType() {
return bizType;
}
public void setBizType(String bizType) {
this.bizType = bizType;
}
@XmlElementWrapper(name = "extend")
@XmlElement(name = "property")
public List<Property> getProperties() {
return properties;
}
public void setProperties(List<Property> properties) {
this.properties = properties;
}
@XmlElementWrapper(name = "details")
@XmlElement(name = "detail")
public List<Detail> getDetails() {
return details;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
}