diff --git a/CHANGE.md b/CHANGE.md
index eb0234ae..b8cd4882 100644
--- a/CHANGE.md
+++ b/CHANGE.md
@@ -305,4 +305,8 @@
+ **去掉httpclient依赖**
- + **去掉redis依赖**
\ No newline at end of file
+ + **去掉redis依赖**
+
+* 2015-06-03
+
+ + **去掉xstream依赖**
\ No newline at end of file
diff --git a/weixin4j-base/pom.xml b/weixin4j-base/pom.xml
index aab4834d..3d74df7e 100644
--- a/weixin4j-base/pom.xml
+++ b/weixin4j-base/pom.xml
@@ -12,11 +12,6 @@
微信开发基础工程
https://github.com/foxinmy/weixin4j/tree/master/weixin4j-base
-
- com.thoughtworks.xstream
- xstream
- 1.4.7
-
com.alibaba
fastjson
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/BaseApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/BaseApi.java
index ab3bf49d..8b37ac49 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/BaseApi.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/api/BaseApi.java
@@ -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 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);
}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java
index 6d936d3c..f05ccb30 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java
@@ -26,6 +26,10 @@ public class WeixinException extends Exception {
this.errorMsg = errorMsg;
}
+ public WeixinException(Throwable e) {
+ super(e);
+ }
+
public String getErrorCode() {
return errorCode;
}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinHttpClient.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinHttpClient.java
index 1203b080..ec7477e6 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinHttpClient.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinHttpClient.java
@@ -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) {
//
String newXml = response.getAsString()
.replaceFirst("", "")
@@ -194,7 +193,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
.replaceFirst("", "")
.replaceFirst("", "")
.replaceFirst("", "");
- xmlResult = XmlStream.get(newXml, XmlResult.class);
+ xmlResult = XmlStream.fromXML(newXml, XmlResult.class);
response.setContent(newXml.getBytes(Consts.UTF_8));
}
response.setXmlResult(true);
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinResponse.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinResponse.java
index 0a3a9c79..131f795f 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinResponse.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/WeixinResponse.java
@@ -43,12 +43,12 @@ public class WeixinResponse extends HttpResponse {
if (isXmlResult) {
@SuppressWarnings("unchecked")
Class clazz = (Class) 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);
}
}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/XmlResult.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/XmlResult.java
index 153b69df..fa173a5b 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/XmlResult.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/XmlResult.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java
index fdfcbf42..a9a304bb 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java
@@ -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());
}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java
index f01e3d34..cb22261a 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java
index 9b434da0..1fb1b4a9 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java
index c010ab74..75e11dca 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java
index ae77d3bc..fd998897 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java
@@ -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 articles;
public MpNews() {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java
index a2c327a4..edb5e678 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java
index 1332ad6c..0fb3de2c 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java
index 7c5d06b9..03362e7d 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java
@@ -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 articles;
public News() {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java
index f86d4a1d..83d5c589 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java
@@ -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;
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java
index 479acb08..91ee2e4f 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/StringUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/StringUtil.java
index 1ed1c910..be20ded0 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/StringUtil.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/StringUtil.java
@@ -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) {
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListWrapper.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListWrapper.java
new file mode 100644
index 00000000..8d85d46c
--- /dev/null
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/ListWrapper.java
@@ -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 implements Serializable {
+
+ private static final long serialVersionUID = 7550802632983954221L;
+
+ private List items;
+
+ public ListWrapper() {
+ items = new ArrayList();
+ }
+
+ @XmlAnyElement(lax = true)
+ public List getItems() {
+ return items;
+ }
+}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/Map2ObjectConverter.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/Map2ObjectConverter.java
deleted file mode 100644
index 6462f9db..00000000
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/Map2ObjectConverter.java
+++ /dev/null
@@ -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 map = new HashMap();
- 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();
-
- }
- }
-}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/README.md
deleted file mode 100644
index cfc071f6..00000000
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/README.md
+++ /dev/null
@@ -1 +0,0 @@
-添加支持
\ No newline at end of file
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java
deleted file mode 100644
index 64591ae1..00000000
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java
+++ /dev/null
@@ -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);
- }
-}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XmlStream.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XmlStream.java
index 5dbea53e..ec4bc5a4 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XmlStream.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XmlStream.java
@@ -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("");
- }
- };
- }
- });
- }
-
- public XmlStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
- super(hierarchicalStreamDriver);
- }
-
- @SuppressWarnings("unchecked")
- public T fromXML(String xml, Class t) {
- return (T) super.fromXML(xml);
- }
-
- @SuppressWarnings("unchecked")
- public T fromXML(InputStream inputStream, Class t) {
- return (T) super.fromXML(inputStream);
- }
-
- public static XmlStream get() {
- XmlStream xstream = new XmlStream();
- xstream.ignoreUnknownElements();
- xstream.autodetectAnnotations(true);
- return xstream;
- }
-
- public static T get(InputStream inputStream, Class clazz) {
- XmlStream xStream = get();
- xStream.alias("xml", clazz);
- xStream.processAnnotations(clazz);
- return xStream.fromXML(inputStream, clazz);
- }
-
- public static T get(String xml, Class 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, Unmarshaller> messageUnmarshaller;
+ private final static Map, Marshaller> messageMarshaller;
+ static {
+ messageUnmarshaller = new HashMap, Unmarshaller>();
+ messageMarshaller = new HashMap, Marshaller>();
+ }
+
+ /**
+ * Xml2Bean
+ *
+ * @param content
+ * xml内容
+ * @param clazz
+ * bean类型
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static T fromXML(InputStream content, Class 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 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 fromXML(String content, Class clazz) {
+ return fromXML(
+ new ByteArrayInputStream(content.getBytes(Consts.UTF_8)), clazz);
+ }
+
+ /**
+ * map2xml
+ *
+ * @param map
+ * value无嵌套的map
+ * @return xml内容
+ */
+ public static String map2xml(Map 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> it = map.entrySet().iterator(); it
+ .hasNext();) {
+ Entry 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 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 xml2map(String content) {
+ Map map = new HashMap();
+ 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 void toXML(T t, OutputStream os) {
+ Class clazz = (Class) 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(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) {
+ ;
+ }
+ }
+ }
+ }
+}
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java
index a29a2c6c..41eab81f 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java
@@ -4,7 +4,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.HashMap;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
@@ -64,14 +63,14 @@ public class CashApi extends MpApi {
obj.put("wxappid", weixinAccount.getId());
String sign = PayUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
obj.put("sign", sign);
- String param = map2xml(new HashMap(obj));
+ String param = XmlStream.map2xml(obj);
String redpack_send_uri = getRequestUri("redpack_send_uri");
WeixinResponse response = null;
InputStream ca = null;
try {
ca = new FileInputStream(caFile);
- SSLHttpClinet request = new SSLHttpClinet(
- weixinAccount.getMchId(), ca);
+ SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
+ ca);
response = request.post(redpack_send_uri, param);
} catch (WeixinException e) {
throw e;
@@ -114,14 +113,14 @@ public class CashApi extends MpApi {
obj.put("device_info", weixinAccount.getDeviceInfo());
String sign = PayUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
obj.put("sign", sign);
- String param = map2xml(new HashMap(obj));
+ String param = XmlStream.map2xml(obj);
String mp_payment_uri = getRequestUri("mp_payment_uri");
WeixinResponse response = null;
InputStream ca = null;
try {
ca = new FileInputStream(caFile);
- SSLHttpClinet request = new SSLHttpClinet(
- weixinAccount.getMchId(), ca);
+ SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
+ ca);
response = request.post(mp_payment_uri, param);
} catch (WeixinException e) {
throw e;
@@ -141,6 +140,6 @@ public class CashApi extends MpApi {
.replaceFirst("", "")
.replaceFirst("", "")
.replaceFirst("", "");
- return XmlStream.get(text, MPPaymentResult.class);
+ return XmlStream.fromXML(text, MPPaymentResult.class);
}
}
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java
index bd506f39..dd33e127 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java
@@ -9,8 +9,8 @@ import java.util.Map;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
-import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.http.weixin.SSLHttpClinet;
+import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail;
@@ -18,6 +18,7 @@ import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.util.RandomUtil;
import com.foxinmy.weixin4j.util.StringUtil;
+import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 代金券API
@@ -73,14 +74,14 @@ public class CouponApi extends MpApi {
map.put("type", "XML");
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
String coupon_send_uri = getRequestUri("coupon_send_uri");
WeixinResponse response = null;
InputStream ca = null;
try {
ca = new FileInputStream(caFile);
- SSLHttpClinet request = new SSLHttpClinet(
- weixinAccount.getMchId(), ca);
+ SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
+ ca);
response = request.post(coupon_send_uri, param);
} catch (WeixinException e) {
throw e;
@@ -116,9 +117,10 @@ public class CouponApi extends MpApi {
map.put("coupon_stock_id", couponStockId);
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
String couponstock_query_uri = getRequestUri("couponstock_query_uri");
- WeixinResponse response = weixinClient.post(couponstock_query_uri, param);
+ WeixinResponse response = weixinClient.post(couponstock_query_uri,
+ param);
return response.getAsObject(new TypeReference() {
});
}
@@ -140,9 +142,10 @@ public class CouponApi extends MpApi {
map.put("coupon_id", couponId);
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
String coupondetail_query_uri = getRequestUri("coupondetail_query_uri");
- WeixinResponse response = weixinClient.post(coupondetail_query_uri, param);
+ WeixinResponse response = weixinClient.post(coupondetail_query_uri,
+ param);
return response.getAsObject(new TypeReference() {
});
}
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay2Api.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay2Api.java
index f079e47b..4b1d5cc4 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay2Api.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay2Api.java
@@ -34,7 +34,7 @@ import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
-import com.foxinmy.weixin4j.mp.payment.conver.RefundConverter;
+import com.foxinmy.weixin4j.mp.payment.conver.ListsuffixResultConverter;
import com.foxinmy.weixin4j.mp.payment.v2.Order;
import com.foxinmy.weixin4j.mp.payment.v2.RefundRecord;
import com.foxinmy.weixin4j.mp.payment.v2.RefundResult;
@@ -442,8 +442,8 @@ public class Pay2Api extends PayApi {
String sign = PayUtil.paysignMd5(map, weixinAccount.getPartnerKey());
map.put("sign", sign.toLowerCase());
WeixinResponse response = weixinClient.get(refundquery_uri, map);
- return RefundConverter.fromXML(response.getAsString(),
- RefundRecord.class);
+ return ListsuffixResultConverter.containRefundConvert(
+ response.getAsString(), RefundRecord.class);
}
@Override
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java
index 7c40702f..14345d52 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java
@@ -25,8 +25,7 @@ import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
-import com.foxinmy.weixin4j.mp.payment.conver.CouponConverter;
-import com.foxinmy.weixin4j.mp.payment.conver.RefundConverter;
+import com.foxinmy.weixin4j.mp.payment.conver.ListsuffixResultConverter;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.payment.v3.Order;
import com.foxinmy.weixin4j.mp.payment.v3.RefundRecord;
@@ -40,6 +39,7 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
import com.foxinmy.weixin4j.util.StringUtil;
+import com.foxinmy.weixin4j.xml.XmlStream;
/**
* V3(商户平台版)支付API
@@ -77,10 +77,11 @@ public class Pay3Api extends PayApi {
Map map = baseMap(idQuery);
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
String orderquery_uri = getRequestUri("orderquery_v3_uri");
WeixinResponse response = weixinClient.post(orderquery_uri, param);
- return CouponConverter.fromXML(response.getAsString(), Order.class);
+ return ListsuffixResultConverter.containCouponConvert(
+ response.getAsString(), Order.class);
}
/**
@@ -139,7 +140,7 @@ public class Pay3Api extends PayApi {
String sign = PayUtil
.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
ca);
response = request.post(refund_uri, param);
@@ -156,8 +157,8 @@ public class Pay3Api extends PayApi {
}
}
}
- return CouponConverter.fromXML(response.getAsString(),
- RefundResult.class);
+ return response.getAsObject(new TypeReference() {
+ });
}
/**
@@ -219,7 +220,7 @@ public class Pay3Api extends PayApi {
String sign = PayUtil
.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
WeixinResponse response = request.post(reverse_uri, param);
return response.getAsObject(new TypeReference() {
});
@@ -256,10 +257,10 @@ public class Pay3Api extends PayApi {
}
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
String shorturl_uri = getRequestUri("p_shorturl_uri");
WeixinResponse response = weixinClient.post(shorturl_uri, param);
- map = xml2map(response.getAsString());
+ map = XmlStream.xml2map(response.getAsString());
return map.get("short_url");
}
@@ -283,7 +284,7 @@ public class Pay3Api extends PayApi {
IdType.TRADENO));
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
String closeorder_uri = getRequestUri("closeorder_uri");
WeixinResponse response = weixinClient.post(closeorder_uri, param);
return response.getAsObject(new TypeReference() {
@@ -332,7 +333,7 @@ public class Pay3Api extends PayApi {
map.put("bill_type", billType.name());
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
WeixinResponse response = weixinClient.post(downloadbill_uri, param);
BufferedReader reader = null;
@@ -391,10 +392,10 @@ public class Pay3Api extends PayApi {
Map map = baseMap(idQuery);
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
WeixinResponse response = weixinClient.post(refundquery_uri, param);
- return RefundConverter.fromXML(response.getAsString(),
- RefundRecord.class);
+ return ListsuffixResultConverter.containRefundDetailConvert(
+ response.getAsString(), RefundRecord.class);
}
/**
@@ -432,7 +433,7 @@ public class Pay3Api extends PayApi {
map.putAll((Map) JSON.toJSON(returnXml));
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
map.put("sign", sign);
- String param = map2xml(map);
+ String param = XmlStream.map2xml(map);
WeixinResponse response = weixinClient.post(pay_report_uri, param);
return response.getAsXmlResult();
}
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/JsPayNotify.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/JsPayNotify.java
index b414942c..aa5b9f4c 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/JsPayNotify.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/JsPayNotify.java
@@ -1,7 +1,8 @@
package com.foxinmy.weixin4j.mp.payment;
+import javax.xml.bind.annotation.XmlElement;
+
import com.alibaba.fastjson.annotation.JSONField;
-import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* JSAPI支付回调时的POST信息
@@ -19,12 +20,12 @@ public class JsPayNotify extends PayBaseInfo {
/**
* 用户的openid
*/
- @XStreamAlias("OpenId")
+ @XmlElement(name = "OpenId")
private String openid;
/**
* 是否关注公众号
*/
- @XStreamAlias("IsSubscribe")
+ @XmlElement(name = "IsSubscribe")
private int issubscribe;
public String getOpenid() {
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java
index ea51b92c..4013a21c 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java
@@ -2,10 +2,12 @@ package com.foxinmy.weixin4j.mp.payment;
import java.util.Date;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.util.RandomUtil;
-import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 刷卡支付
@@ -16,7 +18,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
-@XStreamAlias("xml")
+@XmlRootElement(name = "xml")
public class MicroPayPackage extends PayPackage {
private static final long serialVersionUID = 8944928173669656177L;
@@ -27,19 +29,19 @@ public class MicroPayPackage extends PayPackage {
/**
* 微信支付分配的商户号 必须
*/
- @XStreamAlias("mch_id")
+ @XmlElement(name = "mch_id")
@JSONField(name = "mch_id")
private String mchId;
/**
* 微信支付分配的终端设备号 非必须
*/
- @XStreamAlias("device_info")
+ @XmlElement(name = "device_info")
@JSONField(name = "device_info")
private String deviceInfo;
/**
* 随机字符串,不长于 32 位 必须
*/
- @XStreamAlias("nonce_str")
+ @XmlElement(name = "nonce_str")
@JSONField(name = "nonce_str")
private String nonceStr;
/**
@@ -49,7 +51,7 @@ public class MicroPayPackage extends PayPackage {
/**
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
*/
- @XStreamAlias("auth_code")
+ @XmlElement(name = "auth_code")
@JSONField(name = "auth_code")
private String authCode;
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayBaseInfo.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayBaseInfo.java
index 7b82868f..00f843c1 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayBaseInfo.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayBaseInfo.java
@@ -2,9 +2,10 @@ package com.foxinmy.weixin4j.mp.payment;
import java.io.Serializable;
+import javax.xml.bind.annotation.XmlElement;
+
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.type.SignType;
-import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 基本信息
@@ -22,27 +23,27 @@ public class PayBaseInfo implements Serializable {
/**
* 公众号ID
*/
- @XStreamAlias("AppId")
+ @XmlElement(name = "AppId")
private String appId;
/**
* 时间戳
*/
- @XStreamAlias("TimeStamp")
+ @XmlElement(name = "TimeStamp")
private String timeStamp;
/**
* 随机字符串
*/
- @XStreamAlias("NonceStr")
+ @XmlElement(name = "NonceStr")
private String nonceStr;
/**
* 签名结果
*/
- @XStreamAlias("AppSignature")
+ @XmlElement(name = "AppSignature")
private String paySign;
/**
* 签名方式
*/
- @XStreamAlias("SignMethod")
+ @XmlElement(name = "SignMethod")
private String signType;
public String getAppId() {
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java
index 7ba0eb3e..4306f8d7 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayPackage.java
@@ -3,9 +3,10 @@ package com.foxinmy.weixin4j.mp.payment;
import java.io.Serializable;
import java.util.Date;
+import javax.xml.bind.annotation.XmlElement;
+
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.util.DateUtil;
-import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 订单信息
@@ -35,45 +36,45 @@ public class PayPackage implements Serializable {
/**
* 商户系统内部的订单号 ,32 个字符内 、可包含字母 ,确保 在商户系统唯一 必须
*/
- @XStreamAlias("out_trade_no")
+ @XmlElement(name = "out_trade_no")
@JSONField(name = "out_trade_no")
private String outTradeNo;
/**
* 订单总金额,单位为分,不能带小数点 必须
*/
- @XStreamAlias("total_fee")
+ @XmlElement(name = "total_fee")
@JSONField(name = "total_fee")
private String totalFee;
/**
* 订单生成的机器 IP 必须
*/
- @XStreamAlias("spbill_create_ip")
+ @XmlElement(name = "spbill_create_ip")
@JSONField(name = "spbill_create_ip")
private String spbillCreateIp;
/**
* 订单生成时间,格式为 yyyyMMddHHmmss,如 2009 年 12月25日9点10分10秒表示为 20091225091010。时区 为
* GMT+8 beijing。该时间取 自商户服务器 非必须
*/
- @XStreamAlias("time_start")
+ @XmlElement(name = "time_start")
@JSONField(name = "time_start")
private String timeStart;
/**
* 订单失效时间,格为 yyyyMMddHHmmss,如 2009 年 12月27日9点10分10秒表示为 20091227091010。时区 为
* GMT+8 beijing。该时间取 自商户服务商品标记 非必须
*/
- @XStreamAlias("time_expire")
+ @XmlElement(name = "time_expire")
@JSONField(name = "time_expire")
private String timeExpire;
/**
* 商品标记,该字段不能随便填,不使用请填空 非必须
*/
- @XStreamAlias("goods_tag")
+ @XmlElement(name = "goods_tag")
@JSONField(name = "goods_tag")
private String goodsTag;
/**
* 通知地址接收微信支付成功通知 必须
*/
- @XStreamAlias("notify_url")
+ @XmlElement(name = "notify_url")
@JSONField(name = "notify_url")
private String notifyUrl;
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayRequest.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayRequest.java
index f47d209f..2e8ac9fd 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayRequest.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayRequest.java
@@ -1,9 +1,10 @@
package com.foxinmy.weixin4j.mp.payment;
+import javax.xml.bind.annotation.XmlElement;
+
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
-import com.thoughtworks.xstream.annotations.XStreamAlias;
public class PayRequest extends PayBaseInfo {
@@ -12,7 +13,7 @@ public class PayRequest extends PayBaseInfo {
/**
* 订单详情扩展 订单信息组成该字符串
*/
- @XStreamAlias("Package")
+ @XmlElement(name = "Package")
@JSONField(name = "package")
private String packageInfo;
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java
index 0374c766..e7731205 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java
@@ -220,12 +220,13 @@ public class PayUtil {
* @return 预支付对象
*/
private final static WeixinHttpClient httpClient = new WeixinHttpClient();
+
public static PrePay createPrePay(PayPackageV3 payPackage, String paySignKey)
throws PayException {
if (StringUtil.isBlank(payPackage.getSign())) {
payPackage.setSign(paysignMd5(payPackage, paySignKey));
}
- String payJsRequestXml = XmlStream.to(payPackage).replaceAll("__", "_");
+ String payJsRequestXml = XmlStream.toXML(payPackage);
try {
WeixinResponse response = httpClient.post(Consts.UNIFIEDORDER,
payJsRequestXml);
@@ -355,7 +356,7 @@ public class PayUtil {
map.put("retcode", payRequest.getRetCode());
map.put("reterrmsg", payRequest.getRetMsg());
payRequest.setPaySign(paysignSha(map));
- return XmlStream.to(payRequest);
+ return XmlStream.toXML(payRequest);
}
/**
@@ -406,7 +407,7 @@ public class PayUtil {
throws WeixinException {
String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey());
payPackage.setSign(sign);
- String para = XmlStream.to(payPackage).replaceAll("__", "_");
+ String para = XmlStream.toXML(payPackage);
WeixinResponse response = httpClient.post(Consts.MICROPAYURL, para);
return response
.getAsObject(new TypeReference() {
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/CouponConverter.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/CouponConverter.java
deleted file mode 100644
index cf06f65b..00000000
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/CouponConverter.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.foxinmy.weixin4j.mp.payment.conver;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo;
-import com.foxinmy.weixin4j.mp.payment.v3.Order;
-import com.foxinmy.weixin4j.mp.payment.v3.RefundResult;
-import com.foxinmy.weixin4j.xml.XmlStream;
-import com.thoughtworks.xstream.converters.Converter;
-import com.thoughtworks.xstream.converters.MarshallingContext;
-import com.thoughtworks.xstream.converters.UnmarshallingContext;
-import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
-import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-import com.thoughtworks.xstream.mapper.Mapper;
-
-/**
- * V3订单详情转换类
- *
- * @className OrderConverter
- * @author jy
- * @date 2015年3月24日
- * @since JDK 1.7
- * @see
- */
-public class CouponConverter {
-
- private final static XmlStream xStream = XmlStream.get();
- private final static Mapper mapper;
- private final static ReflectionProvider reflectionProvider;
- private final static Pattern pattern = Pattern.compile("(_\\d)$");
- private static Class COUPON_CLASS = CouponInfo.class;
- private static Class> clazz;
-
- static {
- xStream.processAnnotations(new Class[] { COUPON_CLASS });
- xStream.registerConverter(new $());
- mapper = xStream.getMapper();
- reflectionProvider = xStream.getReflectionProvider();
- }
-
- public static T fromXML(String xml, Class clazz) {
- CouponConverter.clazz = clazz;
- xStream.processAnnotations(clazz);
- return xStream.fromXML(xml, clazz);
- }
-
- private static class $ implements Converter {
- @Override
- public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
- return clazz.equals(Order.class)
- || clazz.equals(RefundResult.class);
- }
-
- @Override
- public void marshal(Object source, HierarchicalStreamWriter writer,
- MarshallingContext context) {
- new ReflectionConverter(mapper, reflectionProvider).marshal(source,
- writer, context);
- }
-
- @Override
- public Object unmarshal(HierarchicalStreamReader reader,
- UnmarshallingContext context) {
- Object object = null;
- try {
- object = clazz.newInstance();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- Matcher matcher = null;
- Map> outMap = new HashMap>();
- while (reader.hasMoreChildren()) {
- reader.moveDown();
- String nodeName = reader.getNodeName();
- String fieldName = mapper.realMember(clazz, nodeName);
- Field field = reflectionProvider.getFieldOrNull(clazz,
- fieldName);
- if (field != null) {
- Object value = context.convertAnother(object,
- field.getType());
- reflectionProvider.writeField(object, fieldName, value,
- field.getDeclaringClass());
- } else if ((matcher = pattern.matcher(nodeName)).find()) {
- String key = matcher.group();
- Map innerMap = null;
- if ((innerMap = outMap.get(key)) == null) {
- innerMap = new HashMap();
- outMap.put(key, innerMap);
- }
- innerMap.put(nodeName.replace(key, ""), reader.getValue());
- }
- reader.moveUp();
- }
- if (!outMap.isEmpty()) {
- StringBuilder couponXml = new StringBuilder();
- couponXml.append("");
- for (Iterator>> outIt = outMap
- .entrySet().iterator(); outIt.hasNext();) {
- couponXml.append("<")
- .append(COUPON_CLASS.getCanonicalName())
- .append(">");
- for (Iterator> innerIt = outIt.next()
- .getValue().entrySet().iterator(); innerIt
- .hasNext();) {
- Entry entry = innerIt.next();
- couponXml.append("<").append(entry.getKey())
- .append(">");
- couponXml.append(entry.getValue());
- couponXml.append("").append(entry.getKey())
- .append(">");
- }
- couponXml.append("")
- .append(COUPON_CLASS.getCanonicalName())
- .append(">");
- }
- couponXml.append("
");
- reflectionProvider.writeField(object, "couponList",
- xStream.fromXML(couponXml.toString(), List.class),
- List.class.getDeclaringClass());
- }
- return object;
- }
- }
-}
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/ListsuffixResultConverter.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/ListsuffixResultConverter.java
new file mode 100644
index 00000000..7e0955b7
--- /dev/null
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/ListsuffixResultConverter.java
@@ -0,0 +1,319 @@
+package com.foxinmy.weixin4j.mp.payment.conver;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlRootElement;
+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.stream.StreamSource;
+
+import com.foxinmy.weixin4j.model.Consts;
+import com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo;
+import com.foxinmy.weixin4j.util.ReflectionUtil;
+import com.foxinmy.weixin4j.util.StringUtil;
+import com.foxinmy.weixin4j.xml.ListWrapper;
+import com.foxinmy.weixin4j.xml.XmlStream;
+
+/**
+ * 对 后缀为_$n 的 xml节点转换
+ *
+ * @className ListsuffixResultConverter
+ * @author jy
+ * @date 2015年3月24日
+ * @since JDK 1.7
+ * @see
+ */
+public class ListsuffixResultConverter {
+
+ private final static Pattern SUFFIX_PATTERN = Pattern.compile("(_\\d)$");
+
+ private final static Pattern TWO_SUFFIX_PATTERN = Pattern
+ .compile("_\\d{1,}_\\d{1,}$");
+
+ /**
+ * 对包含 coupon_id_$n 节点的转换 如V3订单查询接口
+ *
+ * @param content
+ * @param clazz
+ * @return
+ */
+ public static T containCouponConvert(String content, Class clazz) {
+ return convert(content, clazz, "couponList");
+ }
+
+ /**
+ * 对包含 refund_id_$n 节点的转换 如V2退款查询接口
+ *
+ * @param content
+ * @param clazz
+ * @return
+ */
+ public static T containRefundConvert(String content, Class clazz) {
+ return convert(content, clazz, "refundList");
+ }
+
+ /**
+ * 对同时包含 refund_id_$n 和 coupon_refund_id_$n_$m 节点的转换 如V3退款查询接口
+ *
+ * @param content
+ * @param clazz
+ * @return
+ */
+ public static T containRefundDetailConvert(String content,
+ Class clazz) {
+ T t = XmlStream.fromXML(content, clazz);
+ Class> wrapperClazz = ReflectionUtil.getFieldGenericType(t,
+ "refundList");
+ XMLStreamReader xr = null;
+ try {
+ xr = XMLInputFactory.newInstance().createXMLStreamReader(
+ new StringReader(content));
+ Matcher matcher = null;
+ Map> refundMap = new HashMap>();
+ Map couponMap = new HashMap();
+ while (true) {
+ int event = xr.next();
+ if (event == XMLStreamConstants.END_DOCUMENT) {
+ break;
+ } else if (event == XMLStreamConstants.START_ELEMENT) {
+ String name = xr.getLocalName();
+ if ((matcher = SUFFIX_PATTERN.matcher(name)).find()) {
+ 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 key = matcher.group();
+ if ((matcher = TWO_SUFFIX_PATTERN.matcher(name))
+ .find()) {
+ key = matcher.group().replaceFirst(
+ SUFFIX_PATTERN.pattern(), "");
+ StringBuilder sb = null;
+ if ((sb = couponMap.get(key)) == null) {
+ sb = new StringBuilder();
+ couponMap.put(key, sb);
+ }
+ String reverserName = new StringBuffer(
+ new StringBuilder(name)
+ .reverse()
+ .toString()
+ .replaceFirst("^(\\d_)", ""))
+ .reverse().toString();
+ sb.append("<").append(reverserName)
+ .append(">");
+ sb.append(xr.getText());
+ sb.append("").append(reverserName)
+ .append(">");
+ } else {
+ Map innerMap = null;
+ if ((innerMap = refundMap.get(key)) == null) {
+ innerMap = new HashMap();
+ refundMap.put(key, innerMap);
+ }
+ innerMap.put(name.replace(key, ""),
+ xr.getText());
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!refundMap.isEmpty()) {
+ String itemName = StringUtil.uncapitalize(wrapperClazz
+ .getSimpleName());
+ XmlRootElement rootElement = wrapperClazz
+ .getAnnotation(XmlRootElement.class);
+ if (rootElement != null
+ && StringUtil.isNotBlank(rootElement.name())) {
+ try {
+ if (!rootElement.name().equals(
+ XmlRootElement.class.getMethod("name")
+ .getDefaultValue().toString())) {
+ itemName = rootElement.name();
+ }
+ } catch (Exception e) {
+ ;
+ }
+ }
+ List