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(""); - } - couponXml.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(""); + } 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 refundList = new ArrayList(); + StringBuilder xmlBuilder = new StringBuilder(); + for (Iterator>> refundIt = refundMap + .entrySet().iterator(); refundIt.hasNext();) { + xmlBuilder.delete(0, xmlBuilder.length()); + xmlBuilder.append("<").append(itemName).append(">"); + Entry> refundEntry = refundIt + .next(); + for (Iterator> refundInnerIt = refundEntry + .getValue().entrySet().iterator(); refundInnerIt + .hasNext();) { + Entry entry = refundInnerIt.next(); + xmlBuilder.append("<").append(entry.getKey()) + .append(">"); + xmlBuilder.append(entry.getValue()); + xmlBuilder.append(""); + } + xmlBuilder.append(""); + Object refund = XmlStream.fromXML(xmlBuilder.toString(), + wrapperClazz); + StringBuilder couponXml = couponMap.get(refundEntry + .getKey()); + if (couponXml != null) { + ListWrapper listWrapper = toListWrapper( + String.format("%s", + couponXml.toString()), CouponInfo.class); + if (listWrapper != null) { + ReflectionUtil.invokeSetterMethod(refund, + "couponList", listWrapper.getItems(), + List.class); + } + } + refundList.add(refund); + } + ReflectionUtil.invokeSetterMethod(t, "refundList", refundList, + List.class); + } + } catch (XMLStreamException e) { + throw new IllegalArgumentException(e); + } finally { + try { + if (xr != null) { + xr.close(); + } + } catch (XMLStreamException e) { + ; + } + } + return t; + } + + public static T convert(String content, Class clazz, + String listPropertyName) { + T t = XmlStream.fromXML(content, clazz); + Class wrapperClazz = ReflectionUtil.getFieldGenericType(t, + listPropertyName); + ListWrapper listWrapper = toListWrapper(content, wrapperClazz); + if (listWrapper != null) { + ReflectionUtil.invokeSetterMethod(t, listPropertyName, + listWrapper.getItems(), List.class); + } + return t; + } + + @SuppressWarnings("unchecked") + public static ListWrapper toListWrapper(String content, + Class clazz) { + XMLStreamReader xr = null; + XMLStreamWriter xw = null; + try { + xr = XMLInputFactory.newInstance().createXMLStreamReader( + new StringReader(content)); + Matcher matcher = null; + Map> outMap = 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(); + Map innerMap = null; + if ((innerMap = outMap.get(key)) == null) { + innerMap = new HashMap(); + outMap.put(key, innerMap); + } + innerMap.put(name.replace(key, ""), + xr.getText()); + } + } + } + } + } + if (!outMap.isEmpty()) { + StringWriter sw = new StringWriter(); + xw = XMLOutputFactory.newInstance().createXMLStreamWriter(sw); + xw.writeStartDocument(Consts.UTF_8.name(), "1.0"); + xw.writeStartElement(clazz.getCanonicalName()); + String itemName = StringUtil + .uncapitalize(clazz.getSimpleName()); + XmlRootElement rootElement = clazz + .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) { + ; + } + } + for (Iterator>> outIt = outMap + .entrySet().iterator(); outIt.hasNext();) { + xw.writeStartElement(itemName); + for (Iterator> innerIt = outIt.next() + .getValue().entrySet().iterator(); innerIt + .hasNext();) { + Entry entry = innerIt.next(); + xw.writeStartElement(entry.getKey()); + xw.writeCharacters(entry.getValue()); + xw.writeEndElement(); + } + xw.writeEndElement(); + } + xw.writeEndElement(); + xw.writeEndDocument(); + JAXBContext ctx = JAXBContext.newInstance(ListWrapper.class, + clazz); + Unmarshaller u = ctx.createUnmarshaller(); + return u.unmarshal( + new StreamSource(new StringReader(sw.getBuffer() + .toString())), ListWrapper.class).getValue(); + } + return null; + } catch (XMLStreamException e) { + throw new IllegalArgumentException(e); + } catch (JAXBException e) { + throw new RuntimeException(e); + } finally { + try { + if (xw != null) { + xw.close(); + } + if (xr != null) { + xr.close(); + } + } catch (XMLStreamException e) { + ; + } + } + } +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/RefundConverter.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/RefundConverter.java deleted file mode 100644 index ed614ac0..00000000 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/conver/RefundConverter.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.foxinmy.weixin4j.mp.payment.conver; - -import java.lang.reflect.Field; -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 com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo; -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; - -/** - * 退款查询接口调用结果转换类 - * - * @className RefundConverter - * @author jy - * @date 2014年11月2日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundRecord - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundDetail - * @see com.foxinmy.weixin4j.mp.payment.v3.RefundRecord - * @see com.foxinmy.weixin4j.mp.payment.v3.RefundDetail - */ -public class RefundConverter { - private final static XmlStream xStream = XmlStream.get(); - private final static Mapper mapper; - private final static ReflectionProvider reflectionProvider; - private final static Pattern REFUND_PATTERN = Pattern.compile("_\\d{1,}$"); - private final static Pattern COUPON_PATTERN = Pattern - .compile("_\\d{1,}_\\d{1,}$"); - private static Class clazz; - private final static Class COUPON_CLASS = CouponInfo.class; - private final static Class REFUNDRECORD2 = com.foxinmy.weixin4j.mp.payment.v2.RefundRecord.class; - private final static Class REFUNDRECORD3 = com.foxinmy.weixin4j.mp.payment.v3.RefundRecord.class; - - static { - xStream.processAnnotations(new Class[] { REFUNDRECORD2, REFUNDRECORD3 }); - xStream.aliasField("refund_state", - com.foxinmy.weixin4j.mp.payment.v2.RefundDetail.class, - "refundStatus"); - xStream.registerConverter(new $()); - mapper = xStream.getMapper(); - reflectionProvider = xStream.getReflectionProvider(); - } - - public static T fromXML(String xml, Class clazz) { - RefundConverter.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(REFUNDRECORD2) || clazz.equals(REFUNDRECORD3); - } - - @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 refund = null; - try { - refund = clazz.newInstance(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - Matcher matcher = null; - Map> refundMap = new HashMap>(); - Map> couponMap = 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(refund, - field.getType()); - reflectionProvider.writeField(refund, fieldName, value, - field.getDeclaringClass()); - } else if ((matcher = REFUND_PATTERN.matcher(nodeName)).find()) { - String key = matcher.group(); - Map innerMap = null; - if ((matcher = COUPON_PATTERN.matcher(nodeName)).find()) { - key = matcher.group(); - if ((innerMap = couponMap.get(key)) == null) { - innerMap = new HashMap(); - couponMap.put(key, innerMap); - } - } else { - if ((innerMap = refundMap - .get(String.format("%s_", key))) == null) { - innerMap = new HashMap(); - refundMap.put(String.format("%s_", key), innerMap); - } - } - innerMap.put(nodeName.replaceFirst(key, ""), - reader.getValue()); - } - reader.moveUp(); - } - if (!refundMap.isEmpty()) { - StringBuilder detailXml = new StringBuilder(); - detailXml.append(""); - String detailCanonicalName = clazz.getCanonicalName() - .replaceFirst("RefundRecord", "RefundDetail"); - for (Iterator>> refundIT = refundMap - .entrySet().iterator(); refundIT.hasNext();) { - detailXml.append("<").append(detailCanonicalName) - .append(">"); - Entry> refundEntry = refundIT - .next(); - for (Iterator> innerIt = refundEntry - .getValue().entrySet().iterator(); innerIt - .hasNext();) { - Entry entry = innerIt.next(); - detailXml.append("<").append(entry.getKey()) - .append(">"); - detailXml.append(entry.getValue()); - detailXml.append(""); - } - if (!couponMap.isEmpty()) { - detailXml.append(""); - Iterator>> couponIT = couponMap - .entrySet().iterator(); - while (couponIT.hasNext()) { - Entry> couponEntry = couponIT - .next(); - if (couponEntry.getKey().startsWith( - refundEntry.getKey())) { - detailXml - .append("<") - .append(COUPON_CLASS.getCanonicalName()) - .append(">"); - for (Iterator> innerIt = couponEntry - .getValue().entrySet().iterator(); innerIt - .hasNext();) { - Entry entry = innerIt - .next(); - detailXml.append("<") - .append(entry.getKey()).append(">"); - detailXml.append(entry.getValue()); - detailXml.append(""); - } - detailXml - .append(""); - couponIT.remove(); - } - } - detailXml.append(""); - } - detailXml.append(""); - } - detailXml.append(""); - reflectionProvider.writeField(refund, "details", - xStream.fromXML(detailXml.toString(), List.class), - List.class.getDeclaringClass()); - } - return refund; - } - } -} \ No newline at end of file diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponDetail.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponDetail.java index dcf61352..e9a4e2e0 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponDetail.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponDetail.java @@ -2,6 +2,8 @@ package com.foxinmy.weixin4j.mp.payment.coupon; import java.util.Date; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.payment.v3.ApiResult; import com.foxinmy.weixin4j.mp.type.CouponStatus; @@ -9,7 +11,6 @@ import com.foxinmy.weixin4j.mp.type.CouponStockType; import com.foxinmy.weixin4j.mp.type.CouponType; import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.StringUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 代金券详细 @@ -27,143 +28,143 @@ public class CouponDetail extends ApiResult { /** * 代金券批次Id */ - @XStreamAlias("coupon_stock_id") + @XmlElement(name = "coupon_stock_id") @JSONField(name = "coupon_stock_id") private String couponStockId; /** * 批次类型;1-批量型,2-触发型 */ - @XStreamAlias("coupon_stock_type") + @XmlElement(name = "coupon_stock_type") @JSONField(name = "coupon_stock_type") private int couponStockType; /** * 代金券id */ - @XStreamAlias("coupon_id") + @XmlElement(name = "coupon_id") @JSONField(name = "coupon_id") private String couponId; /** * 代金券面值,单位是分 */ - @XStreamAlias("coupon_value") + @XmlElement(name = "coupon_value") @JSONField(name = "coupon_value") private int couponValue; /** * 代金券使用最低限额,单位是分 */ - @XStreamAlias("coupon_mininum") + @XmlElement(name = "coupon_mininum") @JSONField(name = "coupon_mininum") private int couponMininum; /** * 代金券名称 */ - @XStreamAlias("coupon_name") + @XmlElement(name = "coupon_name") @JSONField(name = "coupon_name") private String couponName; /** * 代金券状态:2-已激活,4-已锁定,8-已实扣 */ - @XStreamAlias("coupon_state") + @XmlElement(name = "coupon_state") @JSONField(name = "coupon_state") private int couponStatus; /** * 代金券类型:1-代金券无门槛,2-代金券有门槛互斥,3-代金券有门槛叠加, */ - @XStreamAlias("coupon_type") + @XmlElement(name = "coupon_type") @JSONField(name = "coupon_type") private int couponType; /** * 代金券描述 */ - @XStreamAlias("coupon_desc") + @XmlElement(name = "coupon_desc") @JSONField(name = "coupon_desc") private String couponDesc; /** * 代金券实际使用金额 */ - @XStreamAlias("coupon_use_value") + @XmlElement(name = "coupon_use_value") @JSONField(name = "coupon_use_value") private int couponUseValue; /** * 代金券剩余金额:部分使用情况下,可能会存在券剩余金额 */ - @XStreamAlias("coupon_remain_value") + @XmlElement(name = "coupon_remain_value") @JSONField(name = "coupon_remain_value") private int couponRemainValue; /** * 生效开始时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("begin_time") + @XmlElement(name = "begin_time") @JSONField(name = "begin_time") private String beginTime; /** * 生效结束时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("end_time") + @XmlElement(name = "end_time") @JSONField(name = "end_time") private String endTime; /** * 发放时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("send_time") + @XmlElement(name = "send_time") @JSONField(name = "send_time") private String sendTime; /** * 使用时间:格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("use_time") + @XmlElement(name = "use_time") @JSONField(name = "use_time") private String useTime; /** * 使用单号:代金券使用后,关联的大单收单单号 */ - @XStreamAlias("trade_no") + @XmlElement(name = "trade_no") @JSONField(name = "trade_no") private String tradeNo; /** * 消耗方商户id:代金券使用后,消耗方商户id */ - @XStreamAlias("consumer_mch_id") + @XmlElement(name = "consumer_mch_id") @JSONField(name = "consumer_mch_id") private String consumerMchId; /** * 消耗方商户名称:代金券使用后,消耗方商户名称 */ - @XStreamAlias("consumer_mch_name") + @XmlElement(name = "consumer_mch_name") @JSONField(name = "consumer_mch_name") private String consumerMchName; /** * 消耗方商户appid:代金券使用后,消耗方商户appid */ - @XStreamAlias("consumer_mch_appid") + @XmlElement(name = "consumer_mch_appid") @JSONField(name = "consumer_mch_appid") private String consumerMchAppid; /** * 发放来源:代金券发放来源 */ - @XStreamAlias("send_source") + @XmlElement(name = "send_source") @JSONField(name = "send_source") private String sendSource; /** * 是否允许部分使用:该代金券是否允许部分使用标识:1-表示支持部分使用 */ - @XStreamAlias("is_partial_use") + @XmlElement(name = "is_partial_use") @JSONField(name = "is_partial_use") private int isPartialUse; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponInfo.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponInfo.java index 0455ccc1..95e99acd 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponInfo.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponInfo.java @@ -2,8 +2,12 @@ package com.foxinmy.weixin4j.mp.payment.coupon; import java.io.Serializable; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.alibaba.fastjson.annotation.JSONField; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 代金券信息(订单,退款中体现) @@ -14,6 +18,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) public class CouponInfo implements Serializable { private static final long serialVersionUID = -8744999305258786901L; @@ -21,19 +27,19 @@ public class CouponInfo implements Serializable { /** * 代金券或立减优惠批次ID */ - @XStreamAlias("coupon_batch_id") + @XmlElement(name = "coupon_batch_id") @JSONField(name = "coupon_batch_id") private String couponBatchId; /** * 代金券或立减优惠ID */ - @XStreamAlias("coupon_id") + @XmlElement(name = "coupon_id") @JSONField(name = "coupon_id") private String couponId; /** * 单个代金券或立减优惠支付金额 */ - @XStreamAlias("coupon_fee") + @XmlElement(name = "coupon_fee") @JSONField(name = "coupon_fee") private Integer couponFee; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponResult.java index 8ff7f249..7ed8dfd9 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponResult.java @@ -1,8 +1,9 @@ package com.foxinmy.weixin4j.mp.payment.coupon; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.payment.v3.ApiResult; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 代金券发放结果 @@ -20,49 +21,49 @@ public class CouponResult extends ApiResult { /** * 代金券批次id */ - @XStreamAlias("coupon_stock_id") + @XmlElement(name = "coupon_stock_id") @JSONField(name = "coupon_stock_id") private String couponStockId; /** * 返回记录数 */ - @XStreamAlias("resp_count") + @XmlElement(name = "resp_count") @JSONField(name = "resp_count") private int responseCount; /** * 成功记录数 */ - @XStreamAlias("success_count") + @XmlElement(name = "success_count") @JSONField(name = "success_count") private int successCount; /** * 失败记录数 */ - @XStreamAlias("failed_count") + @XmlElement(name = "failed_count") @JSONField(name = "failed_count") private int failedCount; /** * 用户在商户appid下的唯一标识 */ - @XStreamAlias("openid") + @XmlElement(name = "openid") @JSONField(name = "openid") private String openId; /** * 返回码 SUCCESS或者FAILED */ - @XStreamAlias("ret_code") + @XmlElement(name = "ret_code") @JSONField(name = "ret_code") private String retCode; /** * 代金券id */ - @XStreamAlias("coupon_id") + @XmlElement(name = "coupon_id") @JSONField(name = "coupon_id") private String couponId; /** * 失败描述信息,例如:“用户已达领用上限” */ - @XStreamAlias("ret_msg") + @XmlElement(name = "ret_msg") @JSONField(name = "ret_msg") private String retMsg; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponStock.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponStock.java index 16e0fc50..0db2456b 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponStock.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/coupon/CouponStock.java @@ -2,12 +2,13 @@ package com.foxinmy.weixin4j.mp.payment.coupon; import java.util.Date; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.payment.v3.ApiResult; import com.foxinmy.weixin4j.mp.type.CouponStockStatus; import com.foxinmy.weixin4j.mp.type.CouponType; import com.foxinmy.weixin4j.util.DateUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 代金券信息 @@ -25,91 +26,91 @@ public class CouponStock extends ApiResult { /** * 代金券批次ID */ - @XStreamAlias("coupon_stock_id") + @XmlElement(name = "coupon_stock_id") @JSONField(name = "coupon_stock_id") private String couponStockId; /** * 代金券名称 */ - @XStreamAlias("coupon_name") + @XmlElement(name = "coupon_name") @JSONField(name = "coupon_name") private String couponName; /** * 代金券面额 */ - @XStreamAlias("coupon_value") + @XmlElement(name = "coupon_value") @JSONField(name = "coupon_value") private int couponValue; /** * 代金券使用最低限额 */ - @XStreamAlias("coupon_mininumn") + @XmlElement(name = "coupon_mininumn") @JSONField(name = "coupon_mininumn") private Integer couponMininumn; /** * 代金券类型:1-代金券无门槛,2-代金券有门槛互斥,3-代金券有门槛叠加 */ - @XStreamAlias("coupon_type") + @XmlElement(name = "coupon_type") @JSONField(name = "coupon_type") private int couponType; /** * 批次状态: 1-未激活;2-审批中;4-已激活;8-已作废;16-中止发放; */ - @XStreamAlias("coupon_stock_status") + @XmlElement(name = "coupon_stock_status") @JSONField(name = "coupon_stock_status") private int couponStockStatus; /** * 代金券数量 */ - @XStreamAlias("coupon_total") + @XmlElement(name = "coupon_total") @JSONField(name = "coupon_total") private int couponTotal; /** * 代金券每个人最多能领取的数量, 如果为0,则表示没有限制 */ - @XStreamAlias("max_quota") + @XmlElement(name = "max_quota") @JSONField(name = "max_quota") private Integer maxQuota; /** * 代金券锁定数量 */ - @XStreamAlias("locked_num") + @XmlElement(name = "locked_num") @JSONField(name = "locked_num") private Integer lockedNum; /** * 代金券已使用数量 */ - @XStreamAlias("used_num") + @XmlElement(name = "used_num") @JSONField(name = "used_num") private Integer usedNum; /** * 代金券已经发送的数量 */ - @XStreamAlias("is_send_num") + @XmlElement(name = "is_send_num") @JSONField(name = "is_send_num") private Integer sendNum; /** * 生效开始时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("begin_time") + @XmlElement(name = "begin_time") @JSONField(name = "begin_time") private String beginTime; /** * 生效结束时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("end_time") + @XmlElement(name = "end_time") @JSONField(name = "end_time") private String endTime; /** * 创建时间 格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。 */ - @XStreamAlias("create_time") + @XmlElement(name = "create_time") @JSONField(name = "create_time") private String createTime; /** * 代金券预算额度 */ - @XStreamAlias("coupon_budget") + @XmlElement(name = "coupon_budget") @JSONField(name = "coupon_budget") private Integer couponBudget; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResult.java index b58e1a5d..17dda0f5 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/ApiResult.java @@ -2,10 +2,13 @@ package com.foxinmy.weixin4j.mp.payment.v2; 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.mp.type.SignType; import com.foxinmy.weixin4j.util.StringUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 调用V2.x接口返回的公用字段 @@ -16,6 +19,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ +@XmlAccessorType(XmlAccessType.FIELD) public class ApiResult implements Serializable { private static final long serialVersionUID = -2876899595643466203L; @@ -23,19 +27,19 @@ public class ApiResult implements Serializable { * 是查询结果状态码,0 表明成功,其他表明错误; */ @JSONField(name = "ret_code") - @XStreamAlias("retcode") + @XmlElement(name = "retcode") private int retCode; /** * 是查询结果出错信息; */ @JSONField(name = "ret_msg") - @XStreamAlias("retmsg") + @XmlElement(name = "retmsg") private String retMsg; /** * 是返回信息中的编码方式; */ @JSONField(name = "input_charset") - @XStreamAlias("input_charset") + @XmlElement(name = "input_charset") private String inputCharset; /** * 是财付通商户号,即前文的 partnerid; @@ -44,7 +48,7 @@ public class ApiResult implements Serializable { /** * 多密钥支持的密钥序号,默认 1 */ - @XStreamAlias("sign_key_index") + @XmlElement(name = "sign_key_index") @JSONField(name = "sign_key_index") private Integer signKeyIndex; /** @@ -55,7 +59,7 @@ public class ApiResult implements Serializable { * 签名类型,取值:MD5、RSA */ @JSONField(name = "sign_type") - @XStreamAlias("sign_type") + @XmlElement(name = "sign_type") private SignType signType; public int getRetCode() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java index cb6596f2..408a64fc 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayNotifyV2.java @@ -1,7 +1,8 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import javax.xml.bind.annotation.XmlElement; + import com.foxinmy.weixin4j.mp.payment.JsPayNotify; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2 Native支付回调时POST的信息 @@ -19,7 +20,7 @@ public class NativePayNotifyV2 extends JsPayNotify { /** * 产品ID 可视为订单ID */ - @XStreamAlias("ProductId") + @XmlElement(name = "ProductId") private String productId; public String getProductId() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java index 1ddeeac9..12188c0e 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java @@ -1,7 +1,9 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.foxinmy.weixin4j.mp.model.WeixinMpAccount; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2 Native支付时的回调响应 @@ -12,19 +14,19 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class NativePayResponseV2 extends JsPayRequestV2 { private static final long serialVersionUID = 6119895998783333012L; /** * 返回码 */ - @XStreamAlias("RetCode") + @XmlElement(name = "RetCode") private String retCode; /** * 返回消息 */ - @XStreamAlias("RetErrMsg") + @XmlElement(name = "RetErrMsg") private String retMsg; public NativePayResponseV2(WeixinMpAccount weixinAccount, diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java index 8310e46f..65caa26c 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayFeedback.java @@ -1,7 +1,9 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.foxinmy.weixin4j.mp.payment.PayBaseInfo; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2维权POST的数据 @@ -12,7 +14,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class PayFeedback extends PayBaseInfo { private static final long serialVersionUID = 7230049346213966310L; @@ -20,42 +22,42 @@ public class PayFeedback extends PayBaseInfo { /** * 投诉单号 */ - @XStreamAlias("FeedBackId") + @XmlElement(name = "FeedBackId") private String feedbackId; /** * 用户ID */ - @XStreamAlias("OpenId") + @XmlElement(name = "OpenId") private String openId; /** * 订单交易单号 */ - @XStreamAlias("TransId") + @XmlElement(name = "TransId") private String transId; /** * 投诉原因 */ - @XStreamAlias("Reason") + @XmlElement(name = "Reason") private String reason; /** * 用户希望解决方案 */ - @XStreamAlias("Solution") + @XmlElement(name = "Solution") private String solution; /** * 备注信息+电话 */ - @XStreamAlias("ExtInfo") + @XmlElement(name = "ExtInfo") private String extInfo; /** * 用户上传的图片凭证,最多五张 */ - @XStreamAlias("PicInfo") + @XmlElement(name = "PicInfo") private String picInfo; /** * 通知类型 request 用户提交投诉 confirm 用户确认消除 投诉 reject 用户拒绝消除投诉 */ - @XStreamAlias("MsgType") + @XmlElement(name = "MsgType") private String status; public String getFeedbackId() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java index 896aaf40..12dee987 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayPackageV2.java @@ -2,10 +2,11 @@ package com.foxinmy.weixin4j.mp.payment.v2; import java.util.Date; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.payment.PayPackage; import com.foxinmy.weixin4j.util.DateUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2支付的订单详情 @@ -23,7 +24,7 @@ public class PayPackageV2 extends PayPackage { /** * 银行通道类型 固定为"WX" 非空 */ - @XStreamAlias("bank_type") + @XmlElement(name = "bank_type") @JSONField(name = "bank_type") private String bankType; /** @@ -33,25 +34,25 @@ public class PayPackageV2 extends PayPackage { /** * 支付币种 默认值是"1" 非空 */ - @XStreamAlias("fee_type") + @XmlElement(name = "fee_type") @JSONField(name = "fee_type") private String feeType; /** * 物流费用 可为空 如果有值,必须保 证 transport_fee + product_fee=total_fee */ - @XStreamAlias("transport_fee") + @XmlElement(name = "transport_fee") @JSONField(name = "transport_fee") private String transportFee; /** * 商品费用 可为空 商品费用,单位为分。如果有值,必须保 证 transport_fee +product_fee=total_fee; */ - @XStreamAlias("product_fee") + @XmlElement(name = "product_fee") @JSONField(name = "product_fee") private String productFee; /** * 传入参数字符编码 取值范围:"GBK"、"UTF-8",默认:"GBK" 可为空 */ - @XStreamAlias("input_charset") + @XmlElement(name = "input_charset") @JSONField(name = "input_charset") private String inputCharset; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java index 3da1e613..a0ddfb2b 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/PayWarn.java @@ -1,7 +1,9 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.foxinmy.weixin4j.mp.payment.PayBaseInfo; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2告警通知 @@ -12,7 +14,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class PayWarn extends PayBaseInfo { private static final long serialVersionUID = 2334592957844332640L; @@ -20,17 +22,17 @@ public class PayWarn extends PayBaseInfo { /** * 错误代号 1001=发货超时 */ - @XStreamAlias("ErrorType") + @XmlElement(name = "ErrorType") private String errortype; /** * 错误描述 */ - @XStreamAlias("Description") + @XmlElement(name = "Description") private String description; /** * 错误详情 */ - @XStreamAlias("AlarmContent") + @XmlElement(name = "AlarmContent") private String alarmcontent; public String getErrortype() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetail.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetail.java index bd289041..8831cf5e 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetail.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundDetail.java @@ -1,10 +1,14 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.type.RefundChannel; import com.foxinmy.weixin4j.mp.type.RefundStatus; import com.foxinmy.weixin4j.util.StringUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2退款详细 @@ -15,6 +19,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) public class RefundDetail extends ApiResult { private static final long serialVersionUID = -3687863914168618620L; @@ -22,43 +28,43 @@ public class RefundDetail extends ApiResult { /** * 商户退款单号 */ - @XStreamAlias("out_refund_no") + @XmlElement(name = "out_refund_no") @JSONField(name = "out_refund_no") private String outRefundNo; /** * 微信退款单号 */ - @XStreamAlias("refund_id") + @XmlElement(name = "refund_id") @JSONField(name = "refund_id") private String refundId; /** * 退款渠道 0:退到财付通、1:退到银行; */ - @XStreamAlias("refund_channel") + @XmlElement(name = "refund_channel") @JSONField(name = "refund_channel") private int refundChannel; /** * 退款总金额,单位为分,可以做部分退款 */ - @XStreamAlias("refund_fee") + @XmlElement(name = "refund_fee") @JSONField(name = "refund_fee") private int refundFee; /** * 退款状态 */ - @XStreamAlias("refund_status") + @XmlElement(name = "refund_status") @JSONField(name = "refund_status") private int refundStatus; /** * 转账退款接收退款的财付通帐号 */ - @XStreamAlias("recv_user_id") + @XmlElement(name = "recv_user_id") @JSONField(name = "recv_user_id") private String recvUserId; /** * 转账退款接收退款的姓名(需与接收退款的财付通帐号绑定的姓名一致) */ - @XStreamAlias("reccv_user_name") + @XmlElement(name = "reccv_user_name") @JSONField(name = "reccv_user_name") private String reccvUserName; @@ -135,9 +141,8 @@ public class RefundDetail extends ApiResult { + ", refundChannel=" + refundChannel + ", refundFee=" + refundFee + ", refundStatus=" + refundStatus + ", recvUserId=" + recvUserId + ", reccvUserName=" - + reccvUserName + ", refundChannel=" - + getFormatRefundChannel() + ", refundFee=" - + getFormatRefundFee() + ", refundStatus=" + + reccvUserName + ", refundChannel=" + getFormatRefundChannel() + + ", refundFee=" + getFormatRefundFee() + ", refundStatus=" + getFormatRefundStatus(); } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecord.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecord.java index 69e97a7d..4555b3fb 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecord.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundRecord.java @@ -2,10 +2,13 @@ package com.foxinmy.weixin4j.mp.payment.v2; import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.util.StringUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamOmitField; /** * V2退款记录 @@ -16,7 +19,8 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField; * @since JDK 1.7 * @see com.foxinmy.weixin4j.mp.payment.v2.RefundDetail */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") +@XmlAccessorType(XmlAccessType.FIELD) public class RefundRecord extends ApiResult { private static final long serialVersionUID = -2971132874939642721L; @@ -24,48 +28,52 @@ public class RefundRecord extends ApiResult { /** * 微信订单号 */ - @XStreamAlias("transaction_id") + @XmlElement(name = "transaction_id") @JSONField(name = "transaction_id") private String transactionId; /** * 商户订单号 */ - @XStreamAlias("out_trade_no") + @XmlElement(name = "out_trade_no") @JSONField(name = "out_trade_no") private String outTradeNo; /** * 退款笔数 */ - @XStreamAlias("refund_count") + @XmlElement(name = "refund_count") @JSONField(name = "refund_count") private int count; /** * 退款详情 */ - @XStreamOmitField + @XmlTransient @JSONField(serialize = false, deserialize = false) - private List details; + private List refundList; public String getTransactionId() { return transactionId; } public String getOutTradeNo() { - return StringUtil.isNotBlank(outTradeNo) ? outTradeNo : null; + return outTradeNo; } public int getCount() { return count; } - public List getDetails() { - return details; + public List getRefundList() { + return refundList; + } + + public void setRefundList(List refundList) { + this.refundList = refundList; } @Override public String toString() { return "RefundRecord [transactionId=" + transactionId + ", outTradeNo=" - + outTradeNo + ", count=" + count + ", details=" + details - + ", " + super.toString() + "]"; + + outTradeNo + ", count=" + count + ", refundList=" + + refundList + ", " + super.toString() + "]"; } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResult.java index 1fa00276..8f1fadc3 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/RefundResult.java @@ -1,7 +1,11 @@ package com.foxinmy.weixin4j.mp.payment.v2; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.alibaba.fastjson.annotation.JSONField; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V2退款申请结果 @@ -12,7 +16,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") +@XmlAccessorType(XmlAccessType.FIELD) public class RefundResult extends RefundDetail { private static final long serialVersionUID = -3687863914168618620L; @@ -20,13 +25,13 @@ public class RefundResult extends RefundDetail { /** * 微信订单号 */ - @XStreamAlias("transaction_id") + @XmlElement(name = "transaction_id") @JSONField(name = "transaction_id") private String transactionId; /** * 商户系统内部的订单号 */ - @XStreamAlias("out_trade_no") + @XmlElement(name = "out_trade_no") @JSONField(name = "out_trade_no") private String outTradeNo; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/ApiResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/ApiResult.java index 6dd54c15..4e4dc483 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/ApiResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/ApiResult.java @@ -1,9 +1,12 @@ package com.foxinmy.weixin4j.mp.payment.v3; +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.http.weixin.XmlResult; import com.foxinmy.weixin4j.util.StringUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 调用V3.x接口返回的公用字段 @@ -14,6 +17,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ +@XmlAccessorType(XmlAccessType.FIELD) public class ApiResult extends XmlResult { private static final long serialVersionUID = -8430005768959715444L; @@ -21,25 +25,25 @@ public class ApiResult extends XmlResult { /** * 微信分配的公众账号 ID商户号 非空 */ - @XStreamAlias("appid") + @XmlElement(name = "appid") @JSONField(name = "appid") private String appId; /** * 微信支付分配的商户号 非空 */ - @XStreamAlias("mch_id") + @XmlElement(name = "mch_id") @JSONField(name = "mch_id") private String mchId; /** * 代理模式下分配的商户号 可能为空 */ - @XStreamAlias("sub_mch_id") + @XmlElement(name = "sub_mch_id") @JSONField(name = "sub_mch_id") private String subMchId; /** * 随机字符串 非空 */ - @XStreamAlias("nonce_str") + @XmlElement(name = "nonce_str") @JSONField(name = "nonce_str") private String nonceStr; /** @@ -49,7 +53,7 @@ public class ApiResult extends XmlResult { /** * 微信支付分配的终端设备号 可能为空 */ - @XStreamAlias("device_info") + @XmlElement(name = "device_info") @JSONField(name = "device_info") private String deviceInfo; /** diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPayment.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPayment.java index 0d075db3..a5675e99 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPayment.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPayment.java @@ -2,10 +2,11 @@ package com.foxinmy.weixin4j.mp.payment.v3; import java.io.Serializable; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.type.MPPaymentCheckNameType; import com.foxinmy.weixin4j.util.DateUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 企业付款 @@ -22,7 +23,7 @@ public class MPPayment implements Serializable { /** * 商户订单号 */ - @XStreamAlias("partner_trade_no") + @XmlElement(name = "partner_trade_no") @JSONField(name = "partner_trade_no") private String outTradeNo; /** @@ -34,13 +35,13 @@ public class MPPayment implements Serializable { * * @see com.foxinmy.weixin4j.mp.type.MPPaymentCheckNameType */ - @XStreamAlias("check_name") + @XmlElement(name = "check_name") @JSONField(name = "check_name") private MPPaymentCheckNameType checkNameType; /** * 收款用户真实姓名。 如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名 可选 */ - @XStreamAlias("re_user_name") + @XmlElement(name = "re_user_name") @JSONField(name = "re_user_name") private String userName; /** @@ -54,7 +55,7 @@ public class MPPayment implements Serializable { /** * 调用接口的机器Ip地址 */ - @XStreamAlias("spbill_create_ip") + @XmlElement(name = "spbill_create_ip") @JSONField(name = "spbill_create_ip") private String clientIp; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPaymentResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPaymentResult.java index 8def029a..807662e0 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPaymentResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/MPPaymentResult.java @@ -1,7 +1,8 @@ package com.foxinmy.weixin4j.mp.payment.v3; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 企业付款结果 @@ -20,19 +21,19 @@ public class MPPaymentResult extends ApiResult { * 微信订单订单号 */ @JSONField(name = "payment_no") - @XStreamAlias("payment_no") + @XmlElement(name = "payment_no") private String transactionId; /** * 商户订单号 */ @JSONField(name = "partner_trade_no") - @XStreamAlias("partner_trade_no") + @XmlElement(name = "partner_trade_no") private String outTradeNo; /** * 支付时间 */ @JSONField(name = "payment_time") - @XStreamAlias("payment_time") + @XmlElement(name = "payment_time") private String paymentTime; public String getTransactionId() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayNotifyV3.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayNotifyV3.java index c1f1d187..f7064127 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayNotifyV3.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayNotifyV3.java @@ -1,6 +1,7 @@ package com.foxinmy.weixin4j.mp.payment.v3; -import com.thoughtworks.xstream.annotations.XStreamAlias; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; /** * V3 Native支付回调时POST的信息 @@ -11,7 +12,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class NativePayNotifyV3 extends ApiResult { private static final long serialVersionUID = 4515471400239795492L; @@ -19,7 +20,7 @@ public class NativePayNotifyV3 extends ApiResult { /** * 产品ID 可视为订单ID */ - @XStreamAlias("product_id") + @XmlElement(name = "product_id") private String productId; public String getProductId() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java index 56767122..648d4c5b 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/NativePayResponseV3.java @@ -1,12 +1,13 @@ package com.foxinmy.weixin4j.mp.payment.v3; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.exception.PayException; import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.mp.payment.PayUtil; import com.foxinmy.weixin4j.util.RandomUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamOmitField; /** * V3 Native支付时的回调响应 @@ -17,12 +18,12 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class NativePayResponseV3 extends ApiResult { private static final long serialVersionUID = 6119895998783333012L; - @XStreamOmitField + @XmlTransient @JSONField(serialize = false) private PrePay prePay; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java index 9df9d84b..1faa1203 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Order.java @@ -3,14 +3,19 @@ package com.foxinmy.weixin4j.mp.payment.v3; import java.util.Date; import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo; import com.foxinmy.weixin4j.mp.type.CurrencyType; import com.foxinmy.weixin4j.mp.type.TradeState; import com.foxinmy.weixin4j.mp.type.TradeType; import com.foxinmy.weixin4j.util.DateUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamOmitField; +import com.foxinmy.weixin4j.util.StringUtil; /** * V3订单信息 @@ -21,7 +26,8 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") +@XmlAccessorType(XmlAccessType.FIELD) public class Order extends ApiResult { private static final long serialVersionUID = 5636828325595317079L; @@ -30,19 +36,19 @@ public class Order extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.TradeState */ - @XStreamAlias("trade_state") + @XmlElement(name = "trade_state") @JSONField(name = "trade_state") private TradeState tradeState; /** * 用户的openid */ - @XStreamAlias("openid") + @XmlElement(name = "openid") @JSONField(name = "openid") private String openId; /** * 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效 */ - @XStreamAlias("is_subscribe") + @XmlElement(name = "is_subscribe") @JSONField(name = "is_subscribe") private String isSubscribe; /** @@ -50,43 +56,43 @@ public class Order extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.TradeType */ - @XStreamAlias("trade_type") + @XmlElement(name = "trade_type") @JSONField(name = "trade_type") private TradeType tradeType; /** * 银行类型 */ - @XStreamAlias("bank_type") + @XmlElement(name = "bank_type") @JSONField(name = "bank_type") private String bankType; /** * 订单总金额,单位为分 */ - @XStreamAlias("total_fee") + @XmlElement(name = "total_fee") @JSONField(name = "total_fee") private int totalFee; /** * 现金券支付金额<=订单总金 额,订单总金额-现金券金额 为现金支付金额 */ - @XStreamAlias("coupon_fee") + @XmlElement(name = "coupon_fee") @JSONField(name = "coupon_fee") private Integer couponFee; /** * 代金券或立减优惠使用数量 */ - @XStreamAlias("coupon_count") + @XmlElement(name = "coupon_count") @JSONField(name = "coupon_count") private Integer couponCount; /** * 代金券信息 */ - @XStreamOmitField + @XmlTransient @JSONField(serialize = false) private List couponList; /** * 现金支付金额 */ - @XStreamAlias("cash_fee") + @XmlElement(name = "cash_fee") @JSONField(name = "cash_fee") private int cashFee; /** @@ -94,19 +100,19 @@ public class Order extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("fee_type") + @XmlElement(name = "fee_type") @JSONField(name = "fee_type") private CurrencyType feeType; /** * 微信支付订单号 */ - @XStreamAlias("transaction_id") + @XmlElement(name = "transaction_id") @JSONField(name = "transaction_id") private String transactionId; /** * 商户订单号 */ - @XStreamAlias("out_trade_no") + @XmlElement(name = "out_trade_no") @JSONField(name = "out_trade_no") private String outTradeNo; /** @@ -116,13 +122,13 @@ public class Order extends ApiResult { /** * 支付完成时间,格式为 yyyyMMddhhmmss */ - @XStreamAlias("time_end") + @XmlElement(name = "time_end") @JSONField(name = "time_end") private String timeEnd; /** * 交易状态描述 */ - @XStreamAlias("trade_state_desc") + @XmlElement(name = "trade_state_desc") @JSONField(name = "trade_state_desc") private String tradeStateDesc; @@ -224,7 +230,10 @@ public class Order extends ApiResult { @JSONField(serialize = false, deserialize = false) public Date getFormatTimeEnd() { - return DateUtil.parse2yyyyMMddHHmmss(timeEnd); + if (StringUtil.isNotBlank(timeEnd)) { + return DateUtil.parse2yyyyMMddHHmmss(timeEnd); + } + return null; } public String getTradeStateDesc() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java index 06092b27..c83a7db3 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java @@ -2,12 +2,14 @@ package com.foxinmy.weixin4j.mp.payment.v3; 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.mp.payment.PayPackage; import com.foxinmy.weixin4j.mp.type.TradeType; import com.foxinmy.weixin4j.util.RandomUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V3支付的订单详情 @@ -18,7 +20,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class PayPackageV3 extends PayPackage { private static final long serialVersionUID = 8944928173669656177L; @@ -30,19 +32,19 @@ public class PayPackageV3 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; /** @@ -52,7 +54,7 @@ public class PayPackageV3 extends PayPackage { /** * 交易类型JSAPI、NATIVE、APP 必须 */ - @XStreamAlias("trade_type") + @XmlElement(name = "trade_type") @JSONField(name = "trade_type") private String tradeType; /** @@ -62,7 +64,7 @@ public class PayPackageV3 extends PayPackage { /** * 只在 trade_type 为 NATIVE 时需要填写 非必须 */ - @XStreamAlias("product_id") + @XmlElement(name = "product_id") @JSONField(name = "product_id") private String productId; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PrePay.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PrePay.java index 412a4e02..858f02cd 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PrePay.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PrePay.java @@ -1,7 +1,9 @@ package com.foxinmy.weixin4j.mp.payment.v3; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.foxinmy.weixin4j.mp.type.TradeType; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V3预订单信息 @@ -12,7 +14,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") public class PrePay extends ApiResult { private static final long serialVersionUID = -8430005768959715444L; @@ -22,17 +24,17 @@ public class PrePay extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.TradeType */ - @XStreamAlias("trade_type") + @XmlElement(name = "trade_type") private TradeType tradeType; /** * 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时 */ - @XStreamAlias("prepay_id") + @XmlElement(name = "prepay_id") private String prepayId; /** * trade_type 为 NATIVE 是有 返回,此参数可直接生成二 维码展示出来进行扫码支付 可能为空 */ - @XStreamAlias("code_url") + @XmlElement(name = "code_url") private String codeUrl; public PrePay() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Redpacket.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Redpacket.java index 5f416320..623ee8eb 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Redpacket.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/Redpacket.java @@ -2,9 +2,10 @@ package com.foxinmy.weixin4j.mp.payment.v3; import java.io.Serializable; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.util.DateUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 红包 @@ -22,49 +23,49 @@ public class Redpacket implements Serializable { /** * 商户订单号(每个订单号必须唯一) 组成: mch_id+yyyymmdd+10位一天内不能重复的数字。 */ - @XStreamAlias("mch_billno") + @XmlElement(name = "mch_billno") @JSONField(name = "mch_billno") private String outTradeNo; /** * 提供方名称 必填 */ - @XStreamAlias("nick_name") + @XmlElement(name = "nick_name") @JSONField(name = "nick_name") private String nickName; /** * 红包发送者名称 必填 */ - @XStreamAlias("send_name") + @XmlElement(name = "send_name") @JSONField(name = "send_name") private String sendName; /** * 接收红包的用户的openid */ - @XStreamAlias("re_openid") + @XmlElement(name = "re_openid") @JSONField(name = "re_openid") private String openid; /** * 付款金额,单位分 */ - @XStreamAlias("total_amount") + @XmlElement(name = "total_amount") @JSONField(name = "total_amount") private String totalAmount; /** * 最小红包金额,单位分 */ - @XStreamAlias("min_value") + @XmlElement(name = "min_value") @JSONField(name = "min_value") private String minValue; /** * 最大红包金额,单位分( 最小金额等于最大金额: min_value=max_value =total_amount) */ - @XStreamAlias("max_value") + @XmlElement(name = "max_value") @JSONField(name = "max_value") private String maxValue; /** * 红包发放总人数 */ - @XStreamAlias("total_num") + @XmlElement(name = "total_num") @JSONField(name = "total_num") private int totalNum; /** @@ -74,13 +75,13 @@ public class Redpacket implements Serializable { /** * ip地址 */ - @XStreamAlias("client_ip") + @XmlElement(name = "client_ip") @JSONField(name = "client_ip") private String clientIp; /** * 活动名称 */ - @XStreamAlias("act_name") + @XmlElement(name = "act_name") @JSONField(name = "act_name") private String actName; /** @@ -90,25 +91,25 @@ public class Redpacket implements Serializable { /** * 商户logo的url 非必填 */ - @XStreamAlias("logo_imgurl") + @XmlElement(name = "logo_imgurl") @JSONField(name = "logo_imgurl") private String logoUrl; /** * 分享文案 非必填 */ - @XStreamAlias("share_content") + @XmlElement(name = "share_content") @JSONField(name = "share_content") private String shareContent; /** * 分享链接 非必填 */ - @XStreamAlias("share_url") + @XmlElement(name = "share_url") @JSONField(name = "share_url") private String shareUrl; /** * 分享的图片 非必填 */ - @XStreamAlias("share_imgurl") + @XmlElement(name = "share_imgurl") @JSONField(name = "share_imgurl") private String shareImageUrl; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RedpacketSendResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RedpacketSendResult.java index 48458022..d62321e5 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RedpacketSendResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RedpacketSendResult.java @@ -1,8 +1,9 @@ package com.foxinmy.weixin4j.mp.payment.v3; +import javax.xml.bind.annotation.XmlElement; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.http.weixin.XmlResult; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 发送红包结果 @@ -19,31 +20,31 @@ public class RedpacketSendResult extends XmlResult { /** * 微信分配的公众账号 */ - @XStreamAlias("wxappid") + @XmlElement(name = "wxappid") @JSONField(name = "wxappid") private String appid; /** * 微信支付分配的商户号 */ - @XStreamAlias("mch_id") + @XmlElement(name = "mch_id") @JSONField(name = "mch_id") private String mchId; /** * 商户订单号(每个订单号必须唯一) 组成: mch_id+yyyymmdd+10位一天内不能重复的数字。 */ - @XStreamAlias("mch_billno") + @XmlElement(name = "mch_billno") @JSONField(name = "mch_billno") private String outTradeNo; /** * 接收红包的用户的openid */ - @XStreamAlias("re_openid") + @XmlElement(name = "re_openid") @JSONField(name = "re_openid") private String openid; /** * 付款金额 单位为分 */ - @XStreamAlias("total_amount") + @XmlElement(name = "total_amount") @JSONField(name = "total_amount") private int totalAmount; diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java index 392527d6..5e98eedc 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundDetail.java @@ -2,13 +2,18 @@ package com.foxinmy.weixin4j.mp.payment.v3; import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo; import com.foxinmy.weixin4j.mp.type.CurrencyType; import com.foxinmy.weixin4j.mp.type.RefundChannel; import com.foxinmy.weixin4j.mp.type.RefundStatus; import com.foxinmy.weixin4j.util.StringUtil; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V3退款详细 @@ -19,6 +24,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) public class RefundDetail extends ApiResult { private static final long serialVersionUID = -3687863914168618620L; @@ -26,25 +33,25 @@ public class RefundDetail extends ApiResult { /** * 商户退款单号 */ - @XStreamAlias("out_refund_no") + @XmlElement(name = "out_refund_no") @JSONField(name = "out_refund_no") private String outRefundNo; /** * 微信退款单号 */ - @XStreamAlias("refund_id") + @XmlElement(name = "refund_id") @JSONField(name = "refund_id") private String refundId; /** * 退款渠道:ORIGINAL—原路退款,默认 BALANCE—退回到余额 */ - @XStreamAlias("refund_channel") + @XmlElement(name = "refund_channel") @JSONField(name = "refund_channel") private String refundChannel; /** * 退款总金额,单位为分,可以做部分退款 */ - @XStreamAlias("refund_fee") + @XmlElement(name = "refund_fee") @JSONField(name = "refund_fee") private int refundFee; /** @@ -52,13 +59,13 @@ public class RefundDetail extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("refund_fee_type") + @XmlElement(name = "refund_fee_type") @JSONField(name = "refund_fee_type") private CurrencyType refundFeeType; /** * 订单总金额 */ - @XStreamAlias("total_fee") + @XmlElement(name = "total_fee") @JSONField(name = "total_fee") private int totalFee; /** @@ -66,13 +73,13 @@ public class RefundDetail extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("fee_type") + @XmlElement(name = "fee_type") @JSONField(name = "fee_type") private CurrencyType feeType; /** * 现金支付金额 */ - @XStreamAlias("cash_fee") + @XmlElement(name = "cash_fee") @JSONField(name = "cash_fee") private int cashFee; /** @@ -80,13 +87,13 @@ public class RefundDetail extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("cash_fee_type") + @XmlElement(name = "cash_fee_type") @JSONField(name = "cash_fee_type") private CurrencyType cashFeeType; /** * 现金退款金额 */ - @XStreamAlias("cash_refund_fee") + @XmlElement(name = "cash_refund_fee") @JSONField(name = "cash_refund_fee") private Integer cashRefundFee; /** @@ -94,19 +101,19 @@ public class RefundDetail extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("cash_refund_fee_type") + @XmlElement(name = "cash_refund_fee_type") @JSONField(name = "cash_refund_fee_type") private CurrencyType cashRefundFeeType; /** * 退款状态 */ - @XStreamAlias("refund_status") + @XmlElement(name = "refund_status") @JSONField(name = "refund_status") private String refundStatus; /** * 现金券退款金额<=退款金额,退款金额-现金券退款金额为现金 */ - @XStreamAlias("coupon_refund_fee") + @XmlElement(name = "coupon_refund_fee") @JSONField(name = "coupon_refund_fee") private Integer couponRefundFee; /** @@ -114,7 +121,7 @@ public class RefundDetail extends ApiResult { * color="red">微信支付文档上写的coupon_count,而实际测试拿到的是coupon_refund_count,做个记号。 * */ - @XStreamAlias("coupon_refund_count") + @XmlElement(name = "coupon_refund_count") @JSONField(name = "coupon_refund_count") private Integer couponRefundCount; /** @@ -122,7 +129,8 @@ public class RefundDetail extends ApiResult { * * @see com.foxinmy.weixin4j.mp.payment.coupon.CouponInfo */ - @JSONField(serialize = false) + @XmlTransient + @JSONField(serialize = false, deserialize = false) private List couponList; public String getOutRefundNo() { diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundRecord.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundRecord.java index 7260c48a..10a2e920 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundRecord.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundRecord.java @@ -2,10 +2,14 @@ package com.foxinmy.weixin4j.mp.payment.v3; import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.mp.type.CurrencyType; -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamOmitField; /** * V3退款记录 @@ -14,9 +18,9 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField; * @author jy * @date 2014年11月1日 * @since JDK 1.7 - * @see com.foxinmy.weixin4j.mp.payment.v3.RefundDetail */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") +@XmlAccessorType(XmlAccessType.FIELD) public class RefundRecord extends ApiResult { private static final long serialVersionUID = -2971132874939642721L; @@ -24,19 +28,19 @@ public class RefundRecord extends ApiResult { /** * 微信订单号 */ - @XStreamAlias("transaction_id") + @XmlElement(name = "transaction_id") @JSONField(name = "transaction_id") private String transactionId; /** * 商户订单号 */ - @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 int totalFee; /** @@ -44,13 +48,13 @@ public class RefundRecord extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("fee_type") + @XmlElement(name = "fee_type") @JSONField(name = "fee_type") private CurrencyType feeType; /** * 现金支付金额 */ - @XStreamAlias("cash_fee") + @XmlElement(name = "cash_fee") @JSONField(name = "cash_fee") private int cashFee; /** @@ -58,33 +62,35 @@ public class RefundRecord extends ApiResult { * * @see com.foxinmy.weixin4j.mp.type.CurrencyType */ - @XStreamAlias("cash_fee_type") + @XmlElement(name = "cash_fee_type") @JSONField(name = "cash_fee_type") private CurrencyType cashFeeType; /** * 退款总金额 */ - @XStreamAlias("refund_fee") + @XmlElement(name = "refund_fee") @JSONField(name = "refund_fee") private int refundFee; /** * 代金券或立减优惠退款金额=订单金额-现金退款金额,注意:满立减金额不会退回 */ - @XStreamAlias("coupon_refund_fee") + @XmlElement(name = "coupon_refund_fee") @JSONField(name = "coupon_refund_fee") private Integer couponRefundFee; /** * 退款笔数 */ - @XStreamAlias("refund_count") + @XmlElement(name = "refund_count") @JSONField(name = "refund_count") private int count; /** * 退款详情 + * + * @see com.foxinmy.weixin4j.mp.payment.v3.RefundDetail */ - @XStreamOmitField + @XmlTransient @JSONField(serialize = false, deserialize = false) - private List details; + private List refundList; public String getTransactionId() { return transactionId; @@ -148,12 +154,12 @@ public class RefundRecord extends ApiResult { return count; } - public List getDetails() { - return details; + public List getRefundList() { + return refundList; } - public void setDetails(List details) { - this.details = details; + public void setRefundList(List refundList) { + this.refundList = refundList; } public int getRefundFee() { @@ -178,6 +184,6 @@ public class RefundRecord extends ApiResult { + ", cashFeeType=" + cashFeeType + ", refundFee=" + getFormatRefundFee() + ", couponRefundFee=" + getFormatCouponRefundFee() + ", count=" + count - + ", details=" + details + ", " + super.toString() + "]"; + + ", refundList=" + refundList + ", " + super.toString() + "]"; } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java index f57cb171..4c312b25 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/RefundResult.java @@ -1,7 +1,11 @@ package com.foxinmy.weixin4j.mp.payment.v3; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.alibaba.fastjson.annotation.JSONField; -import com.thoughtworks.xstream.annotations.XStreamAlias; /** * V3退款申请结果 @@ -12,7 +16,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -@XStreamAlias("xml") +@XmlRootElement(name = "xml") +@XmlAccessorType(XmlAccessType.FIELD) public class RefundResult extends RefundDetail { private static final long serialVersionUID = -3687863914168618620L; @@ -20,13 +25,13 @@ public class RefundResult extends RefundDetail { /** * 微信订单号 */ - @XStreamAlias("transaction_id") + @XmlElement(name = "transaction_id") @JSONField(name = "transaction_id") private String transactionId; /** * 商户系统内部的订单号 */ - @XStreamAlias("out_trade_no") + @XmlElement(name = "out_trade_no") @JSONField(name = "out_trade_no") private String outTradeNo; diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java new file mode 100644 index 00000000..3f75032e --- /dev/null +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java @@ -0,0 +1,108 @@ +package com.foxinmy.weixin4j.mp.test; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.util.HashMap; +import java.util.Map; + +import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.mp.payment.conver.ListsuffixResultConverter; +import com.foxinmy.weixin4j.mp.payment.v2.RefundRecord; +import com.foxinmy.weixin4j.mp.payment.v3.Order; +import com.foxinmy.weixin4j.xml.XmlStream; + +public class XmlstreamTest { + + public static void object2xmlWithRootElement() { + Token token = new Token(); + token.setAccessToken("accessToken"); + token.setExpiresIn(12); + token.setTime(13l); + String content = XmlStream.toXML(token); + System.err.println(content); + } + + public static void object2xmlWithoutRootElement() { + String content = "accessToken12"; + System.err.println(XmlStream.fromXML(content, Token.class)); + } + + public static void xml2objectWithRootElement() { + + } + + public static void xml2objectWithoutRootElement() { + + } + + public static void map2xml() { + Map map = new HashMap(); + map.put("name", "weixin4j"); + map.put("year", "2015"); + System.err.println(XmlStream.map2xml(map)); + } + + public static void xml2map() { + String content = ""; + System.err.println(XmlStream.xml2map(content)); + } + + public static void xml2order() throws Exception { + StringBuffer sb = new StringBuffer(); + try { + BufferedReader br = new BufferedReader(new FileReader( + "/Users/jy/Downloads/order.xml")); + String data = null;// 一次读入一行,直到读入null为文件结束 + while ((data = br.readLine()) != null) { + sb.append(data); + } + br.close(); + } catch (Exception e) { + + } + System.err.println(ListsuffixResultConverter.containCouponConvert( + sb.toString(), Order.class)); + } + + public static void xml2refundRecordV2() throws Exception { + StringBuffer sb = new StringBuffer(); + try { + BufferedReader br = new BufferedReader(new FileReader( + "/Users/jy/Downloads/refund_record2.xml")); + String data = null;// 一次读入一行,直到读入null为文件结束 + while ((data = br.readLine()) != null) { + sb.append(data); + } + br.close(); + } catch (Exception e) { + + } + System.err.println(ListsuffixResultConverter.containRefundConvert( + sb.toString(), RefundRecord.class)); + } + + public static void xml2refundRecordV3() throws Exception { + StringBuffer sb = new StringBuffer(); + try { + BufferedReader br = new BufferedReader(new FileReader( + "/Users/jy/Downloads/refund_record3.xml")); + String data = null;// 一次读入一行,直到读入null为文件结束 + while ((data = br.readLine()) != null) { + sb.append(data); + } + br.close(); + } catch (Exception e) { + + } + System.err.println(ListsuffixResultConverter + .containRefundDetailConvert(sb.toString(), com.foxinmy.weixin4j.mp.payment.v3.RefundRecord.class)); + } + + public static void main(String[] args) throws Exception { + // map2xml(); + // xml2map(); + // xml2order(); + // xml2refundRecordV2(); + xml2refundRecordV3(); + } +}