去掉xstream依赖

This commit is contained in:
jinyu 2015-06-03 22:35:25 +08:00
parent e08487b443
commit 19c613f26b
63 changed files with 1230 additions and 897 deletions

View File

@ -305,4 +305,8 @@
+ **去掉httpclient依赖**
+ **去掉redis依赖**
+ **去掉redis依赖**
* 2015-06-03
+ **去掉xstream依赖**

View File

@ -12,11 +12,6 @@
<description>微信开发基础工程</description>
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-base</url>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>

View File

@ -1,15 +1,10 @@
package com.foxinmy.weixin4j.api;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
import com.foxinmy.weixin4j.xml.Map2ObjectConverter;
import com.foxinmy.weixin4j.xml.XmlStream;
import com.thoughtworks.xstream.core.ClassLoaderReference;
import com.thoughtworks.xstream.mapper.DefaultMapper;
/**
* API基础
@ -23,21 +18,6 @@ import com.thoughtworks.xstream.mapper.DefaultMapper;
*/
public abstract class BaseApi {
protected final WeixinHttpClient weixinClient = new WeixinHttpClient();
protected final static XmlStream mapXstream = XmlStream.get();
static {
mapXstream.alias("xml", Map.class);
mapXstream.registerConverter(new Map2ObjectConverter(new DefaultMapper(
new ClassLoaderReference(XmlStream.class.getClassLoader()))));
}
protected String map2xml(Map<?, ?> map) {
return mapXstream.toXML(map).replaceAll("__", "_");
}
@SuppressWarnings("unchecked")
protected Map<String, String> xml2map(String xml) {
return mapXstream.fromXML(xml, Map.class);
}
protected abstract ResourceBundle getWeixinBundle();
@ -55,7 +35,7 @@ public abstract class BaseApi {
m.appendTail(sb);
return sb.toString();
}
protected String getConfigValue(String key) {
return getWeixinBundle().getString(key);
}

View File

@ -26,6 +26,10 @@ public class WeixinException extends Exception {
this.errorMsg = errorMsg;
}
public WeixinException(Throwable e) {
super(e);
}
public String getErrorCode() {
return errorCode;
}

View File

@ -28,7 +28,6 @@ import com.foxinmy.weixin4j.util.ErrorUtil;
import com.foxinmy.weixin4j.util.MapUtil;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.XmlStream;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;
public class WeixinHttpClient extends SimpleHttpClient {
@ -155,7 +154,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
try {
checkXml(response);
return response;
} catch (CannotResolveClassException ex) {
} catch (IllegalArgumentException ex) {
;
}
throw new WeixinException(response.getAsString());
@ -185,7 +184,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
XmlResult xmlResult = null;
try {
xmlResult = response.getAsXmlResult();
} catch (CannotResolveClassException ex) {
} catch (IllegalArgumentException ex) {
// <?xml><root><data..../data></root>
String newXml = response.getAsString()
.replaceFirst("<root>", "<xml>")
@ -194,7 +193,7 @@ public class WeixinHttpClient extends SimpleHttpClient {
.replaceFirst("<retmsg>", "<return_msg>")
.replaceFirst("</retmsg>", "</return_msg>")
.replaceFirst("</root>", "</xml>");
xmlResult = XmlStream.get(newXml, XmlResult.class);
xmlResult = XmlStream.fromXML(newXml, XmlResult.class);
response.setContent(newXml.getBytes(Consts.UTF_8));
}
response.setXmlResult(true);

View File

@ -43,12 +43,12 @@ public class WeixinResponse extends HttpResponse {
if (isXmlResult) {
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) typeReference.getType();
return XmlStream.get(getAsString(), clazz);
return XmlStream.fromXML(getAsString(), clazz);
}
return null;
}
public XmlResult getAsXmlResult() {
return XmlStream.get(getAsString(), XmlResult.class);
return XmlStream.fromXML(getAsString(), XmlResult.class);
}
}

View File

@ -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) {

View File

@ -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());
}

View File

@ -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;
/**
* 图片链接支持JPGPNG格式较好的效果为大图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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -3,9 +3,10 @@ package com.foxinmy.weixin4j.tuple;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* 图文对象(消息内容存储在微信后台)
@ -32,13 +33,13 @@ public class MpNews implements MassTuple, NotifyTuple {
* 上传图文列表后微信返回的媒体ID
*/
@JSONField(name = "media_id")
@XStreamAlias("MediaId")
@XmlElement(name = "MediaId")
private String mediaId;
/**
* 图文列表
*/
@JSONField(name = "articles")
@XStreamOmitField
@XmlTransient
private List<MpArticle> articles;
public MpNews() {

View File

@ -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) {

View File

@ -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) {

View File

@ -3,8 +3,10 @@ package com.foxinmy.weixin4j.tuple;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 图文对象
@ -18,7 +20,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
@XStreamAlias("Articles")
@XmlRootElement(name = "Articles")
public class News implements NotifyTuple {
private static final long serialVersionUID = 3348756809039388415L;
@ -36,7 +38,7 @@ public class News implements NotifyTuple {
* @see com.foxinmy.weixin4j.tuple.Article
*/
@JSONField(name = "articles")
@XStreamAlias("Articles")
@XmlElement(name = "Articles")
private List<Article> articles;
public News() {

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -0,0 +1,23 @@
package com.foxinmy.weixin4j.xml;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
public class ListWrapper<T> implements Serializable {
private static final long serialVersionUID = 7550802632983954221L;
private List<T> items;
public ListWrapper() {
items = new ArrayList<T>();
}
@XmlAnyElement(lax = true)
public List<T> getItems() {
return items;
}
}

View File

@ -1,62 +0,0 @@
package com.foxinmy.weixin4j.xml;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.foxinmy.weixin4j.util.StringUtil;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.collections.MapConverter;
import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;
/**
* Map转换为实体对象
*
* @className Map2ObjectConverter
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
public class Map2ObjectConverter extends MapConverter {
public Map2ObjectConverter(Mapper mapper) {
super(mapper);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
while (reader.hasMoreChildren()) {
reader.moveDown();
map.put(reader.getNodeName(), reader.getValue());
reader.moveUp();
}
return map;
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
Map<?, ?> map = (Map<?, ?>) source;
for (Entry<?, ?> entry : map.entrySet()) {
if (entry.getValue() == null) {
continue;
}
String value = entry.getValue().toString();
if (StringUtil.isBlank(value)) {
continue;
}
ExtendedHierarchicalStreamWriterHelper.startNode(writer, entry
.getKey().toString(), entry.getClass());
writer.setValue(value);
writer.endNode();
}
}
}

View File

@ -1 +0,0 @@
添加<![CDATA[]>支持

View File

@ -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);
}
}

View File

@ -1,84 +1,274 @@
package com.foxinmy.weixin4j.xml;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
public class XmlStream extends com.thoughtworks.xstream.XStream {
public XmlStream() {
super(new Xpp3Driver() {
@Override
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
@Override
protected void writeText(QuickWriter writer, String text) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
}
};
}
});
}
public XmlStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
super(hierarchicalStreamDriver);
}
@SuppressWarnings("unchecked")
public <T> T fromXML(String xml, Class<T> t) {
return (T) super.fromXML(xml);
}
@SuppressWarnings("unchecked")
public <T> T fromXML(InputStream inputStream, Class<T> t) {
return (T) super.fromXML(inputStream);
}
public static XmlStream get() {
XmlStream xstream = new XmlStream();
xstream.ignoreUnknownElements();
xstream.autodetectAnnotations(true);
return xstream;
}
public static <T> T get(InputStream inputStream, Class<T> clazz) {
XmlStream xStream = get();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
return xStream.fromXML(inputStream, clazz);
}
public static <T> T get(String xml, Class<T> clazz) {
XmlStream xStream = get();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
return xStream.fromXML(xml, clazz);
}
public static String to(Object obj) {
XmlStream xStream = get();
Class<?> clazz = obj.getClass();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
return xStream.toXML(obj);
}
public static void to(Object obj, OutputStream out) {
XmlStream xStream = get();
Class<?> clazz = obj.getClass();
xStream.alias("xml", clazz);
xStream.processAnnotations(clazz);
xStream.toXML(obj, out);
}
}
package com.foxinmy.weixin4j.xml;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.StringUtil;
/**
* XML 处理
*
* @className XmlStream
* @author jy
* @date 2015年6月2日
* @since JDK 1.7
* @see
*/
public final class XmlStream {
private final static String ROOT_ELEMENT_XML = "xml";
private final static String XML_VERSION = "1.0";
private final static Map<Class<?>, Unmarshaller> messageUnmarshaller;
private final static Map<Class<?>, Marshaller> messageMarshaller;
static {
messageUnmarshaller = new HashMap<Class<?>, Unmarshaller>();
messageMarshaller = new HashMap<Class<?>, Marshaller>();
}
/**
* Xml2Bean
*
* @param content
* xml内容
* @param clazz
* bean类型
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T fromXML(InputStream content, Class<T> clazz) {
Unmarshaller unmarshaller = messageUnmarshaller.get(clazz);
if (unmarshaller == null) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
unmarshaller = jaxbContext.createUnmarshaller();
messageUnmarshaller.put(clazz, unmarshaller);
} catch (JAXBException e) {
throw new IllegalArgumentException(e);
}
}
try {
Source source = new StreamSource(content);
XmlRootElement rootElement = clazz
.getAnnotation(XmlRootElement.class);
if (rootElement == null) {
JAXBElement<T> jaxbElement = unmarshaller.unmarshal(source,
clazz);
return jaxbElement.getValue();
} else {
return (T) unmarshaller.unmarshal(source);
}
} catch (JAXBException e) {
throw new IllegalArgumentException(e);
} finally {
if (content != null) {
try {
content.close();
} catch (IOException e) {
;
}
}
}
}
/**
* Xml2Bean
*
* @param content
* xml内容
* @param clazz
* bean类型
* @return
*/
public static <T> T fromXML(String content, Class<T> clazz) {
return fromXML(
new ByteArrayInputStream(content.getBytes(Consts.UTF_8)), clazz);
}
/**
* map2xml
*
* @param map
* value无嵌套的map
* @return xml内容
*/
public static String map2xml(Map<String, String> map) {
StringWriter sw = new StringWriter();
try {
XMLStreamWriter xw = XMLOutputFactory.newInstance()
.createXMLStreamWriter(sw);
xw.writeStartDocument(Consts.UTF_8.name(), XML_VERSION);
xw.writeStartElement(ROOT_ELEMENT_XML);
for (Iterator<Entry<String, String>> it = map.entrySet().iterator(); it
.hasNext();) {
Entry<String, String> entry = it.next();
xw.writeStartElement(entry.getKey());
xw.writeCData(entry.getValue());
xw.writeEndElement();
}
xw.writeEndDocument();
xw.flush();
xw.close();
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
} finally {
try {
sw.close();
} catch (IOException e) {
;
}
}
return sw.getBuffer().toString();
}
public static String map2xml(JSONObject json) {
StringWriter sw = new StringWriter();
try {
XMLStreamWriter xw = XMLOutputFactory.newInstance()
.createXMLStreamWriter(sw);
xw.writeStartDocument(Consts.UTF_8.name(), XML_VERSION);
xw.writeStartElement(ROOT_ELEMENT_XML);
Set<String> keys = json.keySet();
for (String key : keys) {
xw.writeStartElement(key);
xw.writeCData(json.getString(key));
xw.writeEndElement();
}
xw.writeEndDocument();
xw.flush();
xw.close();
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
} finally {
try {
sw.close();
} catch (IOException e) {
;
}
}
return sw.getBuffer().toString();
}
/**
* xml2map
*
* @param content
* 无嵌套节点的xml内容
* @return map对象
*/
public static Map<String, String> xml2map(String content) {
Map<String, String> map = new HashMap<String, String>();
StringReader sr = new StringReader(content);
try {
XMLStreamReader xr = XMLInputFactory.newInstance()
.createXMLStreamReader(sr);
while (true) {
int event = xr.next();
if (event == XMLStreamConstants.END_DOCUMENT) {
xr.close();
break;
} else if (event == XMLStreamConstants.START_ELEMENT) {
String name = xr.getLocalName();
while (true) {
event = xr.next();
if (event == XMLStreamConstants.START_ELEMENT) {
name = xr.getLocalName();
} else if (event == XMLStreamConstants.END_ELEMENT) {
break;
} else if (event == XMLStreamConstants.CHARACTERS) {
String value = xr.getText();
map.put(name, value);
}
}
}
}
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
} finally {
sr.close();
}
return map;
}
/**
* Bean2Xml
*
* @param object
* bean对象
* @return xml内容
*/
public static String toXML(Object object) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
toXML(object, os);
return StringUtil.newStringUtf8(os.toByteArray());
}
/**
* Bean2Xml
*
* @param t
* bean对象
* @param os
* 输出流
*/
@SuppressWarnings("unchecked")
public static <T> void toXML(T t, OutputStream os) {
Class<T> clazz = (Class<T>) t.getClass();
Marshaller marshaller = messageMarshaller.get(clazz);
if (marshaller == null) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
marshaller = jaxbContext.createMarshaller();
messageMarshaller.put(clazz, marshaller);
} catch (JAXBException e) {
throw new IllegalArgumentException(e);
}
}
try {
XmlRootElement rootElement = clazz
.getAnnotation(XmlRootElement.class);
if (rootElement == null) {
marshaller.marshal(new JAXBElement<T>(new QName(
ROOT_ELEMENT_XML), clazz, t), os);
} else {
marshaller.marshal(t, os);
}
} catch (Exception e) {
throw new IllegalArgumentException(e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
;
}
}
}
}
}

View File

@ -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<String, Object>(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<String, Object>(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("</mch_appid>", "</appid>")
.replaceFirst("<mchid>", "<mch_id>")
.replaceFirst("</mchid>", "</mch_id>");
return XmlStream.get(text, MPPaymentResult.class);
return XmlStream.fromXML(text, MPPaymentResult.class);
}
}

View File

@ -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<CouponStock>() {
});
}
@ -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<CouponDetail>() {
});
}

View File

@ -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

View File

@ -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<String, String> 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<RefundResult>() {
});
}
/**
@ -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<ApiResult>() {
});
@ -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<ApiResult>() {
@ -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<String, String> 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<String, String>) 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();
}

View File

@ -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() {

View File

@ -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;

View File

@ -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() {

View File

@ -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;

View File

@ -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;

View File

@ -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<com.foxinmy.weixin4j.mp.payment.v3.Order>() {

View File

@ -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<CouponInfo> 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> T fromXML(String xml, Class<T> 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<String, Map<String, String>> outMap = new HashMap<String, Map<String, String>>();
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<String, String> innerMap = null;
if ((innerMap = outMap.get(key)) == null) {
innerMap = new HashMap<String, String>();
outMap.put(key, innerMap);
}
innerMap.put(nodeName.replace(key, ""), reader.getValue());
}
reader.moveUp();
}
if (!outMap.isEmpty()) {
StringBuilder couponXml = new StringBuilder();
couponXml.append("<list>");
for (Iterator<Entry<String, Map<String, String>>> outIt = outMap
.entrySet().iterator(); outIt.hasNext();) {
couponXml.append("<")
.append(COUPON_CLASS.getCanonicalName())
.append(">");
for (Iterator<Entry<String, String>> innerIt = outIt.next()
.getValue().entrySet().iterator(); innerIt
.hasNext();) {
Entry<String, String> entry = innerIt.next();
couponXml.append("<").append(entry.getKey())
.append(">");
couponXml.append(entry.getValue());
couponXml.append("</").append(entry.getKey())
.append(">");
}
couponXml.append("</")
.append(COUPON_CLASS.getCanonicalName())
.append(">");
}
couponXml.append("</list>");
reflectionProvider.writeField(object, "couponList",
xStream.fromXML(couponXml.toString(), List.class),
List.class.getDeclaringClass());
}
return object;
}
}
}

View File

@ -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> T containCouponConvert(String content, Class<T> clazz) {
return convert(content, clazz, "couponList");
}
/**
* 对包含 refund_id_$n 节点的转换 如V2退款查询接口
*
* @param content
* @param clazz
* @return
*/
public static <T> T containRefundConvert(String content, Class<T> clazz) {
return convert(content, clazz, "refundList");
}
/**
* 对同时包含 refund_id_$n coupon_refund_id_$n_$m 节点的转换 如V3退款查询接口
*
* @param content
* @param clazz
* @return
*/
public static <T> T containRefundDetailConvert(String content,
Class<T> 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<String, Map<String, String>> refundMap = new HashMap<String, Map<String, String>>();
Map<String, StringBuilder> couponMap = new HashMap<String, StringBuilder>();
while (true) {
int event = xr.next();
if (event == XMLStreamConstants.END_DOCUMENT) {
break;
} else if (event == XMLStreamConstants.START_ELEMENT) {
String name = xr.getLocalName();
if ((matcher = SUFFIX_PATTERN.matcher(name)).find()) {
while (true) {
event = xr.next();
if (event == XMLStreamConstants.START_ELEMENT) {
name = xr.getLocalName();
} else if (event == XMLStreamConstants.END_ELEMENT) {
break;
} else if (event == XMLStreamConstants.CHARACTERS) {
String key = matcher.group();
if ((matcher = TWO_SUFFIX_PATTERN.matcher(name))
.find()) {
key = matcher.group().replaceFirst(
SUFFIX_PATTERN.pattern(), "");
StringBuilder sb = null;
if ((sb = couponMap.get(key)) == null) {
sb = new StringBuilder();
couponMap.put(key, sb);
}
String reverserName = new StringBuffer(
new StringBuilder(name)
.reverse()
.toString()
.replaceFirst("^(\\d_)", ""))
.reverse().toString();
sb.append("<").append(reverserName)
.append(">");
sb.append(xr.getText());
sb.append("</").append(reverserName)
.append(">");
} else {
Map<String, String> innerMap = null;
if ((innerMap = refundMap.get(key)) == null) {
innerMap = new HashMap<String, String>();
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<Object> refundList = new ArrayList<Object>();
StringBuilder xmlBuilder = new StringBuilder();
for (Iterator<Entry<String, Map<String, String>>> refundIt = refundMap
.entrySet().iterator(); refundIt.hasNext();) {
xmlBuilder.delete(0, xmlBuilder.length());
xmlBuilder.append("<").append(itemName).append(">");
Entry<String, Map<String, String>> refundEntry = refundIt
.next();
for (Iterator<Entry<String, String>> refundInnerIt = refundEntry
.getValue().entrySet().iterator(); refundInnerIt
.hasNext();) {
Entry<String, String> entry = refundInnerIt.next();
xmlBuilder.append("<").append(entry.getKey())
.append(">");
xmlBuilder.append(entry.getValue());
xmlBuilder.append("</").append(entry.getKey())
.append(">");
}
xmlBuilder.append("</").append(itemName).append(">");
Object refund = XmlStream.fromXML(xmlBuilder.toString(),
wrapperClazz);
StringBuilder couponXml = couponMap.get(refundEntry
.getKey());
if (couponXml != null) {
ListWrapper<?> listWrapper = toListWrapper(
String.format("<xml>%s</xml>",
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> T convert(String content, Class<T> 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 <T> ListWrapper<T> toListWrapper(String content,
Class<T> clazz) {
XMLStreamReader xr = null;
XMLStreamWriter xw = null;
try {
xr = XMLInputFactory.newInstance().createXMLStreamReader(
new StringReader(content));
Matcher matcher = null;
Map<String, Map<String, String>> outMap = new HashMap<String, Map<String, String>>();
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<String, String> innerMap = null;
if ((innerMap = outMap.get(key)) == null) {
innerMap = new HashMap<String, String>();
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<Entry<String, Map<String, String>>> outIt = outMap
.entrySet().iterator(); outIt.hasNext();) {
xw.writeStartElement(itemName);
for (Iterator<Entry<String, String>> innerIt = outIt.next()
.getValue().entrySet().iterator(); innerIt
.hasNext();) {
Entry<String, String> 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) {
;
}
}
}
}

View File

@ -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<CouponInfo> COUPON_CLASS = CouponInfo.class;
private final static Class<com.foxinmy.weixin4j.mp.payment.v2.RefundRecord> REFUNDRECORD2 = com.foxinmy.weixin4j.mp.payment.v2.RefundRecord.class;
private final static Class<com.foxinmy.weixin4j.mp.payment.v3.RefundRecord> 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> T fromXML(String xml, Class<T> 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<String, Map<String, String>> refundMap = new HashMap<String, Map<String, String>>();
Map<String, Map<String, String>> couponMap = new HashMap<String, Map<String, String>>();
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<String, String> innerMap = null;
if ((matcher = COUPON_PATTERN.matcher(nodeName)).find()) {
key = matcher.group();
if ((innerMap = couponMap.get(key)) == null) {
innerMap = new HashMap<String, String>();
couponMap.put(key, innerMap);
}
} else {
if ((innerMap = refundMap
.get(String.format("%s_", key))) == null) {
innerMap = new HashMap<String, String>();
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("<list>");
String detailCanonicalName = clazz.getCanonicalName()
.replaceFirst("RefundRecord", "RefundDetail");
for (Iterator<Entry<String, Map<String, String>>> refundIT = refundMap
.entrySet().iterator(); refundIT.hasNext();) {
detailXml.append("<").append(detailCanonicalName)
.append(">");
Entry<String, Map<String, String>> refundEntry = refundIT
.next();
for (Iterator<Entry<String, String>> innerIt = refundEntry
.getValue().entrySet().iterator(); innerIt
.hasNext();) {
Entry<String, String> entry = innerIt.next();
detailXml.append("<").append(entry.getKey())
.append(">");
detailXml.append(entry.getValue());
detailXml.append("</").append(entry.getKey())
.append(">");
}
if (!couponMap.isEmpty()) {
detailXml.append("<couponList class=\"")
.append(ArrayList.class.getCanonicalName())
.append("\">");
Iterator<Entry<String, Map<String, String>>> couponIT = couponMap
.entrySet().iterator();
while (couponIT.hasNext()) {
Entry<String, Map<String, String>> couponEntry = couponIT
.next();
if (couponEntry.getKey().startsWith(
refundEntry.getKey())) {
detailXml
.append("<")
.append(COUPON_CLASS.getCanonicalName())
.append(">");
for (Iterator<Entry<String, String>> innerIt = couponEntry
.getValue().entrySet().iterator(); innerIt
.hasNext();) {
Entry<String, String> entry = innerIt
.next();
detailXml.append("<")
.append(entry.getKey()).append(">");
detailXml.append(entry.getValue());
detailXml.append("</")
.append(entry.getKey()).append(">");
}
detailXml
.append("</")
.append(COUPON_CLASS.getCanonicalName())
.append(">");
couponIT.remove();
}
}
detailXml.append("</couponList>");
}
detailXml.append("</").append(detailCanonicalName)
.append(">");
}
detailXml.append("</list>");
reflectionProvider.writeField(refund, "details",
xStream.fromXML(detailXml.toString(), List.class),
List.class.getDeclaringClass());
}
return refund;
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 {
* 签名类型,取值:MD5RSA
*/
@JSONField(name = "sign_type")
@XStreamAlias("sign_type")
@XmlElement(name = "sign_type")
private SignType signType;
public int getRetCode() {

View File

@ -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() {

View File

@ -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,

View File

@ -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() {

View File

@ -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;

View File

@ -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() {

View File

@ -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();
}
}

View File

@ -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<RefundDetail> details;
private List<RefundDetail> refundList;
public String getTransactionId() {
return transactionId;
}
public String getOutTradeNo() {
return StringUtil.isNotBlank(outTradeNo) ? outTradeNo : null;
return outTradeNo;
}
public int getCount() {
return count;
}
public List<RefundDetail> getDetails() {
return details;
public List<RefundDetail> getRefundList() {
return refundList;
}
public void setRefundList(List<RefundDetail> 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() + "]";
}
}

View File

@ -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;

View File

@ -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;
/**

View File

@ -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;

View File

@ -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() {

View File

@ -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() {

View File

@ -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;

View File

@ -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<CouponInfo> 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() {

View File

@ -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 {
/**
* 交易类型JSAPINATIVEAPP 必须
*/
@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;

View File

@ -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() {

View File

@ -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;

View File

@ -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;

View File

@ -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,做个记号
* </font>
*/
@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<CouponInfo> couponList;
public String getOutRefundNo() {

View File

@ -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<RefundDetail> details;
private List<RefundDetail> refundList;
public String getTransactionId() {
return transactionId;
@ -148,12 +154,12 @@ public class RefundRecord extends ApiResult {
return count;
}
public List<RefundDetail> getDetails() {
return details;
public List<RefundDetail> getRefundList() {
return refundList;
}
public void setDetails(List<RefundDetail> details) {
this.details = details;
public void setRefundList(List<RefundDetail> 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() + "]";
}
}

View File

@ -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;

View File

@ -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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><xml><accessToken>accessToken</accessToken><expiresIn>12</expiresIn><time>13</time></xml>";
System.err.println(XmlStream.fromXML(content, Token.class));
}
public static void xml2objectWithRootElement() {
}
public static void xml2objectWithoutRootElement() {
}
public static void map2xml() {
Map<String, String> map = new HashMap<String, String>();
map.put("name", "weixin4j");
map.put("year", "2015");
System.err.println(XmlStream.map2xml(map));
}
public static void xml2map() {
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><xml><name><![CDATA[weixin4j]]></name><year><![CDATA[2015]]></year></xml>";
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();
}
}