去掉xstream依赖

This commit is contained in:
jinyu
2015-06-03 22:35:25 +08:00
parent e08487b443
commit 19c613f26b
63 changed files with 1230 additions and 897 deletions
-5
View File
@@ -12,11 +12,6 @@
<description>微信开发基础工程</description>
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-base</url>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
@@ -1,15 +1,10 @@
package com.foxinmy.weixin4j.api;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
import com.foxinmy.weixin4j.xml.Map2ObjectConverter;
import com.foxinmy.weixin4j.xml.XmlStream;
import com.thoughtworks.xstream.core.ClassLoaderReference;
import com.thoughtworks.xstream.mapper.DefaultMapper;
/**
* API基础
@@ -23,21 +18,6 @@ import com.thoughtworks.xstream.mapper.DefaultMapper;
*/
public abstract class BaseApi {
protected final WeixinHttpClient weixinClient = new WeixinHttpClient();
protected final static XmlStream mapXstream = XmlStream.get();
static {
mapXstream.alias("xml", Map.class);
mapXstream.registerConverter(new Map2ObjectConverter(new DefaultMapper(
new ClassLoaderReference(XmlStream.class.getClassLoader()))));
}
protected String map2xml(Map<?, ?> map) {
return mapXstream.toXML(map).replaceAll("__", "_");
}
@SuppressWarnings("unchecked")
protected Map<String, String> xml2map(String xml) {
return mapXstream.fromXML(xml, Map.class);
}
protected abstract ResourceBundle getWeixinBundle();
@@ -55,7 +35,7 @@ public abstract class BaseApi {
m.appendTail(sb);
return sb.toString();
}
protected String getConfigValue(String key) {
return getWeixinBundle().getString(key);
}
@@ -26,6 +26,10 @@ public class WeixinException extends Exception {
this.errorMsg = errorMsg;
}
public WeixinException(Throwable e) {
super(e);
}
public String getErrorCode() {
return errorCode;
}
@@ -28,7 +28,6 @@ import com.foxinmy.weixin4j.util.ErrorUtil;
import com.foxinmy.weixin4j.util.MapUtil;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.XmlStream;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;
public class WeixinHttpClient extends SimpleHttpClient {
@@ -155,7 +154,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
try {
checkXml(response);
return response;
} catch (CannotResolveClassException ex) {
} catch (IllegalArgumentException ex) {
;
}
throw new WeixinException(response.getAsString());
@@ -185,7 +184,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
XmlResult xmlResult = null;
try {
xmlResult = response.getAsXmlResult();
} catch (CannotResolveClassException ex) {
} catch (IllegalArgumentException ex) {
// <?xml><root><data..../data></root>
String newXml = response.getAsString()
.replaceFirst("<root>", "<xml>")
@@ -194,7 +193,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
.replaceFirst("<retmsg>", "<return_msg>")
.replaceFirst("</retmsg>", "</return_msg>")
.replaceFirst("</root>", "</xml>");
xmlResult = XmlStream.get(newXml, XmlResult.class);
xmlResult = XmlStream.fromXML(newXml, XmlResult.class);
response.setContent(newXml.getBytes(Consts.UTF_8));
}
response.setXmlResult(true);
@@ -43,12 +43,12 @@ public class WeixinResponse extends HttpResponse {
if (isXmlResult) {
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) typeReference.getType();
return XmlStream.get(getAsString(), clazz);
return XmlStream.fromXML(getAsString(), clazz);
}
return null;
}
public XmlResult getAsXmlResult() {
return XmlStream.get(getAsString(), XmlResult.class);
return XmlStream.fromXML(getAsString(), XmlResult.class);
}
}
@@ -2,9 +2,11 @@ package com.foxinmy.weixin4j.http.weixin;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.util.StringUtil;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 调用接口返回xml格式
@@ -15,25 +17,41 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class XmlResult implements Serializable {
private static final long serialVersionUID = -6185313616955051150L;
@XStreamAlias("return_code")
/**
* 此字段是通信标识,非交易 标识,交易是否成功需要查 看 result_code 来判断非空
*/
@XmlElement(name = "return_code")
@JSONField(name = "return_code")
private String returnCode;// 此字段是通信标识,非交易 标识,交易是否成功需要查 看 result_code 来判断 非空
@XStreamAlias("return_msg")
private String returnCode;
/**
* 返回信息,如非 空,为错误原因 可能为空
*/
@XmlElement(name = "return_msg")
@JSONField(name = "return_msg")
private String returnMsg;// 返回信息,如非 空,为错误原因 可能为空
@XStreamAlias("result_code")
private String returnMsg;
/**
* 业务结果SUCCESS/FAIL 非空
*/
@XmlElement(name = "result_code")
@JSONField(name = "result_code")
private String resultCode;// 业务结果SUCCESS/FAIL 非空
@XStreamAlias("err_code")
private String resultCode;
/**
* 错误代码 可为空
*/
@XmlElement(name = "err_code")
@JSONField(name = "err_code")
private String errCode;// 错误代码 可为空
@XStreamAlias("err_code_des")
private String errCode;
/**
* 结果信息描述 可为空
*/
@XmlElement(name = "err_code_des")
@JSONField(name = "err_code_des")
private String errCodeDes;// 结果信息描述 可为空
private String errCodeDes;
public XmlResult() {
}
@@ -47,36 +65,36 @@ public class XmlResult implements Serializable {
return returnCode;
}
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public String getReturnMsg() {
return StringUtil.isNotBlank(returnMsg) ? returnMsg : null;
}
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
return returnMsg;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getErrCode() {
return errCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
public String getErrCodeDes() {
return errCodeDes;
}
public String getErrCodeDes() {
return StringUtil.isNotBlank(errCodeDes) ? errCodeDes : null;
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
}
public void setErrCodeDes(String errCodeDes) {
@@ -9,7 +9,7 @@ import java.util.Calendar;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.thoughtworks.xstream.XStream;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 用FILE保存TOKEN
@@ -21,7 +21,6 @@ import com.thoughtworks.xstream.XStream;
* @see com.foxinmy.weixin4j.token.TokenCreator
*/
public class FileTokenHolder implements TokenHolder {
private final XStream xstream;
private final String tokenPath;
private final TokenCreator tokenCreator;
@@ -32,11 +31,6 @@ public class FileTokenHolder implements TokenHolder {
public FileTokenHolder(String tokenPath, TokenCreator tokenCreator) {
this.tokenPath = tokenPath;
this.tokenCreator = tokenCreator;
xstream = new XStream();
xstream.ignoreUnknownElements();
xstream.autodetectAnnotations(true);
xstream.alias("xml", Token.class);
xstream.processAnnotations(Token.class);
}
@Override
@@ -48,8 +42,8 @@ public class FileTokenHolder implements TokenHolder {
long now_time = ca.getTimeInMillis();
try {
if (token_file.exists()) {
token = (Token) xstream
.fromXML(new FileInputStream(token_file));
token = XmlStream.fromXML(new FileInputStream(token_file),
Token.class);
long expire_time = token.getTime()
+ (token.getExpiresIn() * 1000) - 2;
if (expire_time > now_time) {
@@ -57,7 +51,7 @@ public class FileTokenHolder implements TokenHolder {
}
}
token = tokenCreator.createToken();
xstream.toXML(token, new FileOutputStream(token_file));
XmlStream.toXML(token, new FileOutputStream(token_file));
} catch (IOException e) {
throw new WeixinException(e.getMessage());
}
@@ -2,8 +2,9 @@ package com.foxinmy.weixin4j.tuple;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 客服消息图文
@@ -21,24 +22,24 @@ public class Article implements Serializable {
/**
* 图文消息标题
*/
@XStreamAlias("Title")
@XmlElement(name = "Title")
private String title;
/**
* 图文消息描述
*/
@JSONField(name = "description")
@XStreamAlias("Description")
@XmlElement(name = "Description")
private String desc;
/**
* 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200
*/
@JSONField(name = "picurl")
@XStreamAlias("PicUrl")
@XmlElement(name = "PicUrl")
private String picUrl;
/**
* 点击图文消息跳转链接
* 点击图文消息跳转链接
*/
@XStreamAlias("Url")
@XmlElement(name = "Url")
private String url;
public Article(String title, String desc, String picUrl, String url) {
@@ -1,7 +1,8 @@
package com.foxinmy.weixin4j.tuple;
import javax.xml.bind.annotation.XmlElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 文件对象
@@ -28,7 +29,7 @@ public class File implements NotifyTuple {
* 上传后的微信返回的媒体ID
*/
@JSONField(name = "media_id")
@XStreamAlias("MediaId")
@XmlElement(name = "MediaId")
private String mediaId;
public File(String mediaId) {
@@ -1,7 +1,8 @@
package com.foxinmy.weixin4j.tuple;
import javax.xml.bind.annotation.XmlElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 图片对象
@@ -28,7 +29,7 @@ public class Image implements MassTuple, NotifyTuple {
* 上传后的微信返回的媒体ID
*/
@JSONField(name = "media_id")
@XStreamAlias("MediaId")
@XmlElement(name = "MediaId")
private String mediaId;
public Image(String mediaId) {
@@ -3,9 +3,10 @@ package com.foxinmy.weixin4j.tuple;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* 图文对象(消息内容存储在微信后台)
@@ -32,13 +33,13 @@ public class MpNews implements MassTuple, NotifyTuple {
* 上传图文列表后微信返回的媒体ID
*/
@JSONField(name = "media_id")
@XStreamAlias("MediaId")
@XmlElement(name = "MediaId")
private String mediaId;
/**
* 图文列表
*/
@JSONField(name = "articles")
@XStreamOmitField
@XmlTransient
private List<MpArticle> articles;
public MpNews() {
@@ -1,7 +1,8 @@
package com.foxinmy.weixin4j.tuple;
import javax.xml.bind.annotation.XmlElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 群发视频对象
@@ -28,7 +29,7 @@ public class MpVideo implements MassTuple {
* 上传视频后微信返回的媒体ID
*/
@JSONField(name = "media_id")
@XStreamAlias("MediaId")
@XmlElement(name = "MediaId")
private String mediaId;
public MpVideo(String mediaId) {
@@ -1,7 +1,8 @@
package com.foxinmy.weixin4j.tuple;
import javax.xml.bind.annotation.XmlElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 音乐对象
@@ -27,31 +28,31 @@ public class Music implements NotifyTuple {
/**
* 音乐标题
*/
@XStreamAlias("Title")
@XmlElement(name = "Title")
private String title;
/**
* 音乐描述
*/
@JSONField(name = "description")
@XStreamAlias("Description")
@XmlElement(name = "Description")
private String desc;
/**
* 音乐链接
*/
@JSONField(name = "musicurl")
@XStreamAlias("MusicUrl")
@XmlElement(name = "MusicUrl")
private String musicUrl;
/**
* 高质量音乐链接,WIFI环境优先使用该链接播放音乐
*/
@JSONField(name = "hqmusicurl")
@XStreamAlias("HQMusicUrl")
@XmlElement(name = "HQMusicUrl")
private String hqMusicUrl;
/**
* 缩略图的媒体id,通过上传多媒体文件,得到的id
*/
@JSONField(name = "thumb_media_id")
@XStreamAlias("ThumbMediaId")
@XmlElement(name = "ThumbMediaId")
private String thumbMediaId;
public Music(String thumbMediaId) {
@@ -3,8 +3,10 @@ package com.foxinmy.weixin4j.tuple;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 图文对象
@@ -18,7 +20,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
@XStreamAlias("Articles")
@XmlRootElement(name = "Articles")
public class News implements NotifyTuple {
private static final long serialVersionUID = 3348756809039388415L;
@@ -36,7 +38,7 @@ public class News implements NotifyTuple {
* @see com.foxinmy.weixin4j.tuple.Article
*/
@JSONField(name = "articles")
@XStreamAlias("Articles")
@XmlElement(name = "Articles")
private List<Article> articles;
public News() {
@@ -1,6 +1,6 @@
package com.foxinmy.weixin4j.tuple;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import javax.xml.bind.annotation.XmlRootElement;
/**
* 文本对象
@@ -14,7 +14,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
@XStreamAlias("Content")
@XmlRootElement(name = "Content")
public class Text implements MassTuple, NotifyTuple {
private static final long serialVersionUID = 520050144519064503L;
@@ -1,8 +1,9 @@
package com.foxinmy.weixin4j.tuple;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* 视频对象
@@ -29,24 +30,24 @@ public class Video implements NotifyTuple {
* 上传视频微信返回的媒体ID
*/
@JSONField(name = "media_id")
@XStreamAlias("MediaId")
@XmlElement(name = "MediaId")
private String mediaId;
/**
* 缩略图的媒体ID(客服消息)
*/
@XStreamOmitField
@JSONField(name = "thumb_media_id")
@XmlTransient
private String thumbMediaId;
/**
* 视频标题
*/
@XStreamAlias("Title")
@XmlElement(name = "Title")
private String title;
/**
* 视频描述
*/
@JSONField(name = "description")
@XStreamAlias("Description")
@XmlElement(name = "Description")
private String desc;
public Video(String mediaId) {
@@ -51,6 +51,23 @@ public final class StringUtil {
return !isBlank(cs);
}
public static String uncapitalize(final String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
char firstChar = str.charAt(0);
if (Character.isLowerCase(firstChar)) {
// already uncapitalized
return str;
}
return new StringBuilder(strLen)
.append(Character.toLowerCase(firstChar))
.append(str.substring(1)).toString();
}
public static String capitalize(final String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
@@ -0,0 +1,23 @@
package com.foxinmy.weixin4j.xml;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
public class ListWrapper<T> implements Serializable {
private static final long serialVersionUID = 7550802632983954221L;
private List<T> items;
public ListWrapper() {
items = new ArrayList<T>();
}
@XmlAnyElement(lax = true)
public List<T> getItems() {
return items;
}
}
@@ -1,62 +0,0 @@
package com.foxinmy.weixin4j.xml;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.foxinmy.weixin4j.util.StringUtil;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.collections.MapConverter;
import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;
/**
* Map转换为实体对象
*
* @className Map2ObjectConverter
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
public class Map2ObjectConverter extends MapConverter {
public Map2ObjectConverter(Mapper mapper) {
super(mapper);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
while (reader.hasMoreChildren()) {
reader.moveDown();
map.put(reader.getNodeName(), reader.getValue());
reader.moveUp();
}
return map;
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
Map<?, ?> map = (Map<?, ?>) source;
for (Entry<?, ?> entry : map.entrySet()) {
if (entry.getValue() == null) {
continue;
}
String value = entry.getValue().toString();
if (StringUtil.isBlank(value)) {
continue;
}
ExtendedHierarchicalStreamWriterHelper.startNode(writer, entry
.getKey().toString(), entry.getClass());
writer.setValue(value);
writer.endNode();
}
}
}
@@ -1 +0,0 @@
添加<![CDATA[]>支持
@@ -1,30 +0,0 @@
package com.foxinmy.weixin4j.xml;
import com.foxinmy.weixin4j.tuple.Text;
import com.thoughtworks.xstream.converters.SingleValueConverter;
/**
* Text回复消息转换
*
* @className TextConverter
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
*/
public class TextConverter implements SingleValueConverter {
@Override
public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
return clazz.equals(Text.class);
}
@Override
public String toString(Object obj) {
return ((Text) obj).getContent();
}
@Override
public Object fromString(String text) {
return new Text(text);
}
}
@@ -1,84 +1,274 @@
package com.foxinmy.weixin4j.xml;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
public class XmlStream extends com.thoughtworks.xstream.XStream {
public XmlStream() {
super(new Xpp3Driver() {
@Override
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
@Override
protected void writeText(QuickWriter writer, String text) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
}
};
}
});
}
public XmlStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
super(hierarchicalStreamDriver);
}
@SuppressWarnings("unchecked")
public <T> T fromXML(String xml, Class<T> t) {
return (T) super.fromXML(xml);
}
@SuppressWarnings("unchecked")
public <T> T fromXML(InputStream inputStream, Class<T> t) {
return (T) super.fromXML(inputStream);
}
public static XmlStream get() {
XmlStream xstream = new XmlStream();
xstream.ignoreUnknownElements();
xstream.autodetectAnnotations(true);
return xstream;
}
public static <T> T get(InputStream inputStream, Class<T> clazz) {
XmlStream xStream = get();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
return xStream.fromXML(inputStream, clazz);
}
public static <T> T get(String xml, Class<T> clazz) {
XmlStream xStream = get();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
return xStream.fromXML(xml, clazz);
}
public static String to(Object obj) {
XmlStream xStream = get();
Class<?> clazz = obj.getClass();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
return xStream.toXML(obj);
}
public static void to(Object obj, OutputStream out) {
XmlStream xStream = get();
Class<?> clazz = obj.getClass();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
xStream.toXML(obj, out);
}
}
package com.foxinmy.weixin4j.xml;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
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.XmlRootElement;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.StringUtil;
/**
* XML 处理
*
* @className XmlStream
* @author jy
* @date 2015年6月2日
* @since JDK 1.7
* @see
*/
public final class XmlStream {
private final static String ROOT_ELEMENT_XML = "xml";
private final static String XML_VERSION = "1.0";
private final static Map<Class<?>, Unmarshaller> messageUnmarshaller;
private final static Map<Class<?>, Marshaller> messageMarshaller;
static {
messageUnmarshaller = new HashMap<Class<?>, Unmarshaller>();
messageMarshaller = new HashMap<Class<?>, Marshaller>();
}
/**
* Xml2Bean
*
* @param content
* xml内容
* @param clazz
* bean类型
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T fromXML(InputStream content, Class<T> clazz) {
Unmarshaller unmarshaller = messageUnmarshaller.get(clazz);
if (unmarshaller == null) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
unmarshaller = jaxbContext.createUnmarshaller();
messageUnmarshaller.put(clazz, unmarshaller);
} catch (JAXBException e) {
throw new IllegalArgumentException(e);
}
}
try {
Source source = new StreamSource(content);
XmlRootElement rootElement = clazz
.getAnnotation(XmlRootElement.class);
if (rootElement == null) {
JAXBElement<T> jaxbElement = unmarshaller.unmarshal(source,
clazz);
return jaxbElement.getValue();
} else {
return (T) unmarshaller.unmarshal(source);
}
} catch (JAXBException e) {
throw new IllegalArgumentException(e);
} finally {
if (content != null) {
try {
content.close();
} catch (IOException e) {
;
}
}
}
}
/**
* Xml2Bean
*
* @param content
* xml内容
* @param clazz
* bean类型
* @return
*/
public static <T> T fromXML(String content, Class<T> clazz) {
return fromXML(
new ByteArrayInputStream(content.getBytes(Consts.UTF_8)), clazz);
}
/**
* map2xml
*
* @param map
* value无嵌套的map
* @return xml内容
*/
public static String map2xml(Map<String, String> map) {
StringWriter sw = new StringWriter();
try {
XMLStreamWriter xw = XMLOutputFactory.newInstance()
.createXMLStreamWriter(sw);
xw.writeStartDocument(Consts.UTF_8.name(), XML_VERSION);
xw.writeStartElement(ROOT_ELEMENT_XML);
for (Iterator<Entry<String, String>> it = map.entrySet().iterator(); it
.hasNext();) {
Entry<String, String> entry = it.next();
xw.writeStartElement(entry.getKey());
xw.writeCData(entry.getValue());
xw.writeEndElement();
}
xw.writeEndDocument();
xw.flush();
xw.close();
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
} finally {
try {
sw.close();
} catch (IOException e) {
;
}
}
return sw.getBuffer().toString();
}
public static String map2xml(JSONObject json) {
StringWriter sw = new StringWriter();
try {
XMLStreamWriter xw = XMLOutputFactory.newInstance()
.createXMLStreamWriter(sw);
xw.writeStartDocument(Consts.UTF_8.name(), XML_VERSION);
xw.writeStartElement(ROOT_ELEMENT_XML);
Set<String> keys = json.keySet();
for (String key : keys) {
xw.writeStartElement(key);
xw.writeCData(json.getString(key));
xw.writeEndElement();
}
xw.writeEndDocument();
xw.flush();
xw.close();
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
} finally {
try {
sw.close();
} catch (IOException e) {
;
}
}
return sw.getBuffer().toString();
}
/**
* xml2map
*
* @param content
* 无嵌套节点的xml内容
* @return map对象
*/
public static Map<String, String> xml2map(String content) {
Map<String, String> map = new HashMap<String, String>();
StringReader sr = new StringReader(content);
try {
XMLStreamReader xr = XMLInputFactory.newInstance()
.createXMLStreamReader(sr);
while (true) {
int event = xr.next();
if (event == XMLStreamConstants.END_DOCUMENT) {
xr.close();
break;
} else if (event == XMLStreamConstants.START_ELEMENT) {
String name = xr.getLocalName();
while (true) {
event = xr.next();
if (event == XMLStreamConstants.START_ELEMENT) {
name = xr.getLocalName();
} else if (event == XMLStreamConstants.END_ELEMENT) {
break;
} else if (event == XMLStreamConstants.CHARACTERS) {
String value = xr.getText();
map.put(name, value);
}
}
}
}
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
} finally {
sr.close();
}
return map;
}
/**
* Bean2Xml
*
* @param object
* bean对象
* @return xml内容
*/
public static String toXML(Object object) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
toXML(object, os);
return StringUtil.newStringUtf8(os.toByteArray());
}
/**
* Bean2Xml
*
* @param t
* bean对象
* @param os
* 输出流
*/
@SuppressWarnings("unchecked")
public static <T> void toXML(T t, OutputStream os) {
Class<T> clazz = (Class<T>) t.getClass();
Marshaller marshaller = messageMarshaller.get(clazz);
if (marshaller == null) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
marshaller = jaxbContext.createMarshaller();
messageMarshaller.put(clazz, marshaller);
} catch (JAXBException e) {
throw new IllegalArgumentException(e);
}
}
try {
XmlRootElement rootElement = clazz
.getAnnotation(XmlRootElement.class);
if (rootElement == null) {
marshaller.marshal(new JAXBElement<T>(new QName(
ROOT_ELEMENT_XML), clazz, t), os);
} else {
marshaller.marshal(t, os);
}
} catch (Exception e) {
throw new IllegalArgumentException(e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
;
}
}
}
}
}