mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03406f128f | ||
|
|
097fc091b1 | ||
|
|
1e67c3f47b | ||
|
|
ed84f511c7 | ||
|
|
05777c664a | ||
|
|
6b522da559 | ||
|
|
8d87609c0b | ||
|
|
b2e1cca6c2 | ||
|
|
f8207ef65f | ||
|
|
924d3c254f | ||
|
|
f585385e6e | ||
|
|
34fda26e02 | ||
|
|
5309e132ce | ||
|
|
15d6b79319 | ||
|
|
0388c8d9dc | ||
|
|
780074f219 | ||
|
|
59bdad92f6 | ||
|
|
5594c8852d | ||
|
|
89a260dded | ||
|
|
b19dc7b0fb | ||
|
|
379aae95f1 | ||
|
|
6c45fdacdb | ||
|
|
5f456eb521 | ||
|
|
27ce2a2746 | ||
|
|
d5b3239a01 | ||
|
|
7972733feb | ||
|
|
30f22896b1 | ||
|
|
d0a452904a | ||
|
|
b5f0ee75b0 | ||
|
|
123e5ef973 | ||
|
|
23c96d9076 | ||
|
|
9363a67538 | ||
|
|
7b3a3a4c2f | ||
|
|
5e7d1ebbbd | ||
|
|
d87fe63591 | ||
|
|
cc3714c599 | ||
|
|
fe8c70849a | ||
|
|
a25d2edc2f | ||
|
|
c722496167 | ||
|
|
a6db21fbc8 | ||
|
|
9bbdc3b2a0 | ||
|
|
293ef256b6 |
10
README.md
10
README.md
@@ -2,6 +2,12 @@ weixin-java-tools
|
||||
|
||||
[](https://travis-ci.org/chanjarster/weixin-java-tools)
|
||||

|
||||
[](https://gitter.im/chanjarster/weixin-java-tools?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
===========
|
||||
|
||||
* 群/聊天室:请点击上方的GITTER按钮
|
||||
* 本项目的发布周期:本人子2015年6月开始进入到了一个非常忙碌的状态,且公司目前也没有开发微信相关的项目,因此本项目的维护基本靠“等”。所以靠人不如靠自己,提交pull request吧。
|
||||
|
||||
===========
|
||||
|
||||
@@ -17,7 +23,7 @@ weixin-java-tools
|
||||
<dependency>
|
||||
<groupId>me.chanjar</groupId>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.3</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@@ -27,7 +33,7 @@ weixin-java-tools
|
||||
<dependency>
|
||||
<groupId>me.chanjar</groupId>
|
||||
<artifactId>weixin-java-cp</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.3</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>me.chanjar</groupId>
|
||||
<artifactId>weixin-java-parent</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.3</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>WeiXin Java Tools - Parent</name>
|
||||
<description>微信公众号、企业号上级POM</description>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>me.chanjar</groupId>
|
||||
<artifactId>weixin-java-parent</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.3</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>weixin-java-common</artifactId>
|
||||
|
||||
@@ -30,6 +30,8 @@ public class WxConsts {
|
||||
public static final String CUSTOM_MSG_NEWS = "news";
|
||||
public static final String CUSTOM_MSG_FILE = "file";
|
||||
public static final String CUSTOM_MSG_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
|
||||
public static final String CUSTOM_MSG_SAFE_NO = "0";
|
||||
public static final String CUSTOM_MSG_SAFE_YES = "1";
|
||||
|
||||
///////////////////////
|
||||
// 群发消息的消息类型
|
||||
|
||||
@@ -3,13 +3,13 @@ package me.chanjar.weixin.common.bean;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
|
||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
|
||||
|
||||
/**
|
||||
* 企业号菜单
|
||||
* @author Daniel Qian
|
||||
@@ -19,6 +19,8 @@ public class WxMenu implements Serializable {
|
||||
|
||||
private List<WxMenuButton> buttons = new ArrayList<WxMenuButton>();
|
||||
|
||||
private WxMenuRule matchRule;
|
||||
|
||||
public List<WxMenuButton> getButtons() {
|
||||
return buttons;
|
||||
}
|
||||
@@ -27,6 +29,14 @@ public class WxMenu implements Serializable {
|
||||
this.buttons = buttons;
|
||||
}
|
||||
|
||||
public WxMenuRule getMatchRule() {
|
||||
return matchRule;
|
||||
}
|
||||
|
||||
public void setMatchRule(WxMenuRule matchRule) {
|
||||
this.matchRule = matchRule;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
return WxGsonBuilder.create().toJson(this);
|
||||
}
|
||||
@@ -118,5 +128,74 @@ public class WxMenu implements Serializable {
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class WxMenuRule {
|
||||
private String groupId;
|
||||
private String sex;
|
||||
private String country;
|
||||
private String province;
|
||||
private String city;
|
||||
private String clientPlatformType;
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getClientPlatformType() {
|
||||
return clientPlatformType;
|
||||
}
|
||||
|
||||
public void setClientPlatformType(String clientPlatformType) {
|
||||
this.clientPlatformType = clientPlatformType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "matchrule:{" +
|
||||
"group_id='" + groupId + '\'' +
|
||||
", sex='" + sex + '\'' +
|
||||
", country" + country + '\'' +
|
||||
", province" + province + '\'' +
|
||||
", city" + city + '\'' +
|
||||
", client_platform_type" + clientPlatformType + '\'' +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -248,7 +248,6 @@ public class WxCryptUtil {
|
||||
}
|
||||
}
|
||||
toSign.append("key=" + signKey);
|
||||
System.out.println(toSign.toString());
|
||||
String sign = DigestUtils.md5Hex(toSign.toString())
|
||||
.toUpperCase();
|
||||
return sign;
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.HttpMultipartMode;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
@@ -35,6 +36,7 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload
|
||||
HttpEntity entity = MultipartEntityBuilder
|
||||
.create()
|
||||
.addBinaryBody("media", file)
|
||||
.setMode(HttpMultipartMode.RFC6532)
|
||||
.build();
|
||||
httpPost.setEntity(entity);
|
||||
httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString());
|
||||
|
||||
@@ -10,8 +10,7 @@ package me.chanjar.weixin.common.util.json;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxMenu;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
@@ -21,6 +20,8 @@ import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxMenu;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Daniel Qian
|
||||
@@ -38,6 +39,11 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ
|
||||
}
|
||||
json.add("button", buttonArray);
|
||||
|
||||
if (menu.getMatchRule() != null) {
|
||||
Gson gson = new Gson();
|
||||
json.add("matchrule", gson.toJsonTree(menu.getMatchRule()));
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>me.chanjar</groupId>
|
||||
<artifactId>weixin-java-parent</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.3</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>weixin-java-cp</artifactId>
|
||||
|
||||
@@ -555,7 +555,7 @@ public class WxCpServiceImpl implements WxCpService {
|
||||
throw new RuntimeException("微信服务端异常,超出重试次数");
|
||||
}
|
||||
|
||||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
||||
protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
||||
if (uri.indexOf("access_token=") != -1) {
|
||||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public class WxCpMessage implements Serializable {
|
||||
private String description;
|
||||
private String musicUrl;
|
||||
private String hqMusicUrl;
|
||||
private String safe;
|
||||
private List<WxArticle> articles = new ArrayList<WxArticle>();
|
||||
|
||||
public String getToUser() {
|
||||
@@ -63,6 +64,14 @@ public class WxCpMessage implements Serializable {
|
||||
return msgType;
|
||||
}
|
||||
|
||||
public String getSafe() {
|
||||
return safe;
|
||||
}
|
||||
|
||||
public void setSafe(String safe) {
|
||||
this.safe = safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 请使用
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
|
||||
public class BaseBuilder<T> {
|
||||
@@ -8,6 +9,7 @@ public class BaseBuilder<T> {
|
||||
protected String toUser;
|
||||
protected String toParty;
|
||||
protected String toTag;
|
||||
protected String safe;
|
||||
|
||||
public T agentId(String agentId) {
|
||||
this.agentId = agentId;
|
||||
@@ -29,6 +31,11 @@ public class BaseBuilder<T> {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public T safe(String safe) {
|
||||
this.safe = safe;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public WxCpMessage build() {
|
||||
WxCpMessage m = new WxCpMessage();
|
||||
m.setAgentId(this.agentId);
|
||||
@@ -36,6 +43,8 @@ public class BaseBuilder<T> {
|
||||
m.setToUser(this.toUser);
|
||||
m.setToParty(this.toParty);
|
||||
m.setToTag(this.toTag);
|
||||
m.setSafe(
|
||||
(this.safe == null || "".equals(this.safe))? WxConsts.CUSTOM_MSG_SAFE_NO: this.safe);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>me.chanjar</groupId>
|
||||
<artifactId>weixin-java-parent</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.3</version>
|
||||
</parent>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
<name>WeiXin Java Tools - MP</name>
|
||||
|
||||
@@ -2,6 +2,8 @@ package me.chanjar.weixin.mp.api;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
|
||||
/**
|
||||
@@ -74,4 +76,5 @@ public interface WxMpConfigStorage {
|
||||
|
||||
public File getTmpDirFile();
|
||||
|
||||
public SSLContext getSSLContext();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package me.chanjar.weixin.mp.api;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
|
||||
/**
|
||||
@@ -35,6 +37,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
|
||||
*/
|
||||
protected volatile File tmpDirFile;
|
||||
|
||||
protected volatile SSLContext sslContext;
|
||||
|
||||
public String getAccessToken() {
|
||||
return this.accessToken;
|
||||
}
|
||||
@@ -219,4 +223,13 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
|
||||
this.tmpDirFile = tmpDirFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSLContext getSSLContext() {
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
public void setSSLContext(SSLContext context) {
|
||||
sslContext = context;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import me.chanjar.weixin.mp.bean.result.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -325,6 +324,8 @@ public interface WxMpService {
|
||||
* <pre>
|
||||
* 自定义菜单创建接口
|
||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口
|
||||
* 如果要创建个性化菜单,请设置matchrule属性
|
||||
* 详情请见:http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html
|
||||
* </pre>
|
||||
* @param menu
|
||||
* @throws WxErrorException
|
||||
@@ -340,6 +341,16 @@ public interface WxMpService {
|
||||
*/
|
||||
public void menuDelete() throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 删除个性化菜单接口
|
||||
* 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html
|
||||
* </pre>
|
||||
* @param menuid
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
public void menuDelete(String menuid) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 自定义菜单查询接口
|
||||
@@ -349,6 +360,16 @@ public interface WxMpService {
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
public WxMenu menuGet() throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 测试个性化菜单匹配结果
|
||||
* 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html
|
||||
* </pre>
|
||||
* @param userid 可以是粉丝的OpenID,也可以是粉丝的微信号。
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
public WxMenu menuTryMatch(String userid) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@@ -671,33 +692,57 @@ public interface WxMpService {
|
||||
*/
|
||||
void setMaxRetryTimes(int maxRetryTimes);
|
||||
|
||||
/**
|
||||
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
* @param openId 支付人openId
|
||||
* @param outTradeNo 商户端对应订单号
|
||||
* @param amt 金额(单位元)
|
||||
* @param body 商品描述
|
||||
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
|
||||
* @param ip 发起支付的客户端IP
|
||||
* @param notifyUrl 通知地址
|
||||
* @return
|
||||
*/
|
||||
WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
|
||||
/**
|
||||
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
* @param openId 支付人openId
|
||||
* @param outTradeNo 商户端对应订单号
|
||||
* @param amt 金额(单位元)
|
||||
* @param body 商品描述
|
||||
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
|
||||
* @param ip 发起支付的客户端IP
|
||||
* @param notifyUrl 通知地址
|
||||
* @return
|
||||
* @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getPrepayId(Map<String, String>) instead
|
||||
*/
|
||||
@Deprecated
|
||||
WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
|
||||
|
||||
/**
|
||||
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
|
||||
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
|
||||
* @param openId 支付人openId
|
||||
* @param outTradeNo 商户端对应订单号
|
||||
* @param amt 金额(单位元)
|
||||
* @param body 商品描述
|
||||
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
|
||||
* @param ip 发起支付的客户端IP
|
||||
* @param notifyUrl 通知地址
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
|
||||
/**
|
||||
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
*
|
||||
* @param parameters
|
||||
* All required/optional parameters for weixin payment
|
||||
* @return
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
WxMpPrepayIdResult getPrepayId(Map<String, String> parameters);
|
||||
|
||||
/**
|
||||
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
|
||||
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
|
||||
* @param parameters
|
||||
* the required or optional parameters
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> getJSSDKPayInfo(Map<String, String> parameters);
|
||||
|
||||
/**
|
||||
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
|
||||
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
|
||||
* @param openId 支付人openId
|
||||
* @param outTradeNo 商户端对应订单号
|
||||
* @param amt 金额(单位元)
|
||||
* @param body 商品描述
|
||||
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
|
||||
* @param ip 发起支付的客户端IP
|
||||
* @param notifyUrl 通知地址
|
||||
* @return
|
||||
* @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getJSSDKPayInfo(Map<String, String>) instead
|
||||
*/
|
||||
@Deprecated
|
||||
Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
|
||||
|
||||
/**
|
||||
* 该接口提供所有微信支付订单的查询,当支付通知处理异常戒丢失的情冴,商户可以通过该接口查询订单支付状态。
|
||||
@@ -714,4 +759,23 @@ public interface WxMpService {
|
||||
* @return
|
||||
*/
|
||||
WxMpPayCallback getJSSDKCallbackData(String xmlData);
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 计算Map键值对是否和签名相符,
|
||||
* 按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的 格式(即 key1=value1&key2=value2...)拼接成字符串
|
||||
* </pre>
|
||||
* @param kvm
|
||||
* @param signature
|
||||
* @return
|
||||
*/
|
||||
public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature);
|
||||
|
||||
/**
|
||||
* 发送微信红包给个人用户
|
||||
* @param parameters
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
public WxRedpackResult sendRedpack(Map<String, String> parameters) throws WxErrorException;
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
@@ -67,6 +66,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUserSummary;
|
||||
import me.chanjar.weixin.mp.bean.result.WxRedpackResult;
|
||||
import me.chanjar.weixin.mp.util.http.MaterialDeleteRequestExecutor;
|
||||
import me.chanjar.weixin.mp.util.http.MaterialNewsInfoRequestExecutor;
|
||||
import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor;
|
||||
@@ -75,7 +75,6 @@ import me.chanjar.weixin.mp.util.http.MaterialVoiceAndImageDownloadRequestExecut
|
||||
import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor;
|
||||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
@@ -86,13 +85,16 @@ import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.BasicResponseHandler;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
@@ -228,14 +230,24 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
}
|
||||
|
||||
public void menuCreate(WxMenu menu) throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/create";
|
||||
execute(new SimplePostRequestExecutor(), url, menu.toJson());
|
||||
if (menu.getMatchRule() != null) {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/addconditional";
|
||||
execute(new SimplePostRequestExecutor(), url, menu.toJson());
|
||||
} else {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/create";
|
||||
execute(new SimplePostRequestExecutor(), url, menu.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
public void menuDelete() throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delete";
|
||||
execute(new SimpleGetRequestExecutor(), url, null);
|
||||
}
|
||||
|
||||
public void menuDelete(String menuid) throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional";
|
||||
execute(new SimpleGetRequestExecutor(), url, "menuid=" + menuid);
|
||||
}
|
||||
|
||||
public WxMenu menuGet() throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/get";
|
||||
@@ -250,6 +262,20 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public WxMenu menuTryMatch(String userid) throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/trymatch";
|
||||
try {
|
||||
String resultContent = execute(new SimpleGetRequestExecutor(), url, "user_id=" + userid);
|
||||
return WxMenu.fromJson(resultContent);
|
||||
} catch (WxErrorException e) {
|
||||
// 46003 不存在的菜单数据 46002 不存在的菜单版本
|
||||
if (e.getError().getErrorCode() == 46003 || e.getError().getErrorCode() == 46002) {
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException {
|
||||
return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
|
||||
@@ -506,7 +532,10 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send";
|
||||
String responseContent = execute(new SimplePostRequestExecutor(), url, templateMessage.toJson());
|
||||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
|
||||
return tmpJsonElement.getAsJsonObject().get("msgid").getAsString();
|
||||
final JsonObject jsonObject = tmpJsonElement.getAsJsonObject();
|
||||
if (jsonObject.get("errcode").getAsInt() == 0)
|
||||
return jsonObject.get("msgid").getAsString();
|
||||
throw new WxErrorException(WxError.fromJson(responseContent));
|
||||
}
|
||||
|
||||
public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException {
|
||||
@@ -634,8 +663,9 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
param.addProperty("end_date", SIMPLE_DATE_FORMAT.format(endDate));
|
||||
String responseContent = post(url, param.toString());
|
||||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
|
||||
return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("list"), new TypeToken<List<WxMpUserSummary>>() {
|
||||
}.getType());
|
||||
return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("list"),
|
||||
new TypeToken<List<WxMpUserSummary>>() {
|
||||
}.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -695,7 +725,7 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
throw new RuntimeException("微信服务端异常,超出重试次数");
|
||||
}
|
||||
|
||||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
||||
protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
||||
if (uri.indexOf("access_token=") != -1) {
|
||||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
|
||||
}
|
||||
@@ -741,6 +771,7 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
String http_proxy_username = wxMpConfigStorage.getHttp_proxy_username();
|
||||
String http_proxy_password = wxMpConfigStorage.getHttp_proxy_password();
|
||||
|
||||
final HttpClientBuilder builder = HttpClients.custom();
|
||||
if (StringUtils.isNotBlank(http_proxy_host)) {
|
||||
// 使用代理服务器
|
||||
if (StringUtils.isNotBlank(http_proxy_username)) {
|
||||
@@ -749,18 +780,22 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
credsProvider.setCredentials(
|
||||
new AuthScope(http_proxy_host, http_proxy_port),
|
||||
new UsernamePasswordCredentials(http_proxy_username, http_proxy_password));
|
||||
httpClient = HttpClients
|
||||
.custom()
|
||||
.setDefaultCredentialsProvider(credsProvider)
|
||||
.build();
|
||||
builder
|
||||
.setDefaultCredentialsProvider(credsProvider);
|
||||
} else {
|
||||
// 无需用户认证的代理服务器
|
||||
httpClient = HttpClients.createDefault();
|
||||
}
|
||||
httpProxy = new HttpHost(http_proxy_host, http_proxy_port);
|
||||
} else {
|
||||
httpClient = HttpClients.createDefault();
|
||||
}
|
||||
if (wxConfigProvider.getSSLContext() != null){
|
||||
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
|
||||
wxConfigProvider.getSSLContext(),
|
||||
new String[] { "TLSv1" },
|
||||
null,
|
||||
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
|
||||
builder.setSSLSocketFactory(sslsf);
|
||||
}
|
||||
httpClient = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -776,35 +811,37 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
|
||||
@Override
|
||||
public WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) {
|
||||
String nonce_str = System.currentTimeMillis() + "";
|
||||
|
||||
SortedMap<String, String> packageParams = new TreeMap<String, String>();
|
||||
Map<String, String> packageParams = new HashMap<String, String>();
|
||||
packageParams.put("appid", wxMpConfigStorage.getAppId());
|
||||
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
|
||||
packageParams.put("nonce_str", nonce_str);
|
||||
packageParams.put("body", body);
|
||||
packageParams.put("out_trade_no", outTradeNo);
|
||||
|
||||
packageParams.put("total_fee", (int) (amt * 100) + "");
|
||||
packageParams.put("spbill_create_ip", ip);
|
||||
packageParams.put("notify_url", callbackUrl);
|
||||
packageParams.put("trade_type", tradeType);
|
||||
packageParams.put("openid", openId);
|
||||
|
||||
return getPrepayId(packageParams);
|
||||
}
|
||||
|
||||
public WxMpPrepayIdResult getPrepayId(final Map<String, String> parameters) {
|
||||
String nonce_str = System.currentTimeMillis() + "";
|
||||
|
||||
final SortedMap<String, String> packageParams = new TreeMap<String, String>(parameters);
|
||||
packageParams.put("appid", wxMpConfigStorage.getAppId());
|
||||
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
|
||||
packageParams.put("nonce_str", nonce_str);
|
||||
checkParameters(packageParams);
|
||||
|
||||
String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey());
|
||||
String xml = "<xml>" +
|
||||
"<appid>" + wxMpConfigStorage.getAppId() + "</appid>" +
|
||||
"<mch_id>" + wxMpConfigStorage.getPartnerId() + "</mch_id>" +
|
||||
"<nonce_str>" + nonce_str + "</nonce_str>" +
|
||||
"<sign>" + sign + "</sign>" +
|
||||
"<body><![CDATA[" + body + "]]></body>" +
|
||||
"<out_trade_no>" + outTradeNo + "</out_trade_no>" +
|
||||
"<total_fee>" + packageParams.get("total_fee") + "</total_fee>" +
|
||||
"<spbill_create_ip>" + ip + "</spbill_create_ip>" +
|
||||
"<notify_url>" + callbackUrl + "</notify_url>" +
|
||||
"<trade_type>" + tradeType + "</trade_type>" +
|
||||
"<openid>" + openId + "</openid>" +
|
||||
"</xml>";
|
||||
packageParams.put("sign", sign);
|
||||
|
||||
StringBuilder request = new StringBuilder("<xml>");
|
||||
for (Entry<String, String> para : packageParams.entrySet()) {
|
||||
request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey()));
|
||||
}
|
||||
request.append("</xml>");
|
||||
|
||||
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
|
||||
if (httpProxy != null) {
|
||||
@@ -812,7 +849,7 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
httpPost.setConfig(config);
|
||||
}
|
||||
|
||||
StringEntity entity = new StringEntity(xml, Consts.UTF_8);
|
||||
StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8);
|
||||
httpPost.setEntity(entity);
|
||||
try {
|
||||
CloseableHttpResponse response = getHttpclient().execute(httpPost);
|
||||
@@ -822,17 +859,46 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
WxMpPrepayIdResult wxMpPrepayIdResult = (WxMpPrepayIdResult) xstream.fromXML(responseContent);
|
||||
return wxMpPrepayIdResult;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Failed to get prepay id due to IO exception.", e);
|
||||
}
|
||||
return new WxMpPrepayIdResult();
|
||||
}
|
||||
|
||||
final String[] REQUIRED_ORDER_PARAMETERS = new String[] { "appid", "mch_id", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url",
|
||||
"trade_type", };
|
||||
|
||||
private void checkParameters(Map<String, String> parameters) {
|
||||
for (String para : REQUIRED_ORDER_PARAMETERS) {
|
||||
if (!parameters.containsKey(para))
|
||||
throw new IllegalArgumentException("Reqiured argument '" + para + "' is missing.");
|
||||
}
|
||||
if ("JSAPI".equals(parameters.get("trade_type")) && !parameters.containsKey("openid"))
|
||||
throw new IllegalArgumentException("Reqiured argument 'openid' is missing when trade_type is 'JSAPI'.");
|
||||
if ("NATIVE".equals(parameters.get("trade_type")) && !parameters.containsKey("product_id"))
|
||||
throw new IllegalArgumentException("Reqiured argument 'product_id' is missing when trade_type is 'NATIVE'.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) {
|
||||
WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(openId, outTradeNo, amt, body, tradeType, ip, callbackUrl);
|
||||
Map<String, String> packageParams = new HashMap<String, String>();
|
||||
packageParams.put("appid", wxMpConfigStorage.getAppId());
|
||||
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
|
||||
packageParams.put("body", body);
|
||||
packageParams.put("out_trade_no", outTradeNo);
|
||||
packageParams.put("total_fee", (int) (amt * 100) + "");
|
||||
packageParams.put("spbill_create_ip", ip);
|
||||
packageParams.put("notify_url", callbackUrl);
|
||||
packageParams.put("trade_type", tradeType);
|
||||
packageParams.put("openid", openId);
|
||||
|
||||
return getJSSDKPayInfo(packageParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getJSSDKPayInfo(Map<String, String> parameters) {
|
||||
WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(parameters);
|
||||
String prepayId = wxMpPrepayIdResult.getPrepay_id();
|
||||
if (prepayId == null || prepayId.equals("")) {
|
||||
throw new RuntimeException("get prepayid error");
|
||||
throw new RuntimeException(String.format("Failed to get prepay id due to error code '%s'(%s).", wxMpPrepayIdResult.getErr_code(), wxMpPrepayIdResult.getErr_code_des()));
|
||||
}
|
||||
|
||||
Map<String, String> payInfo = new HashMap<String, String>();
|
||||
@@ -850,44 +916,44 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
|
||||
@Override
|
||||
public WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo) {
|
||||
String nonce_str = System.currentTimeMillis() + "";
|
||||
String nonce_str = System.currentTimeMillis() + "";
|
||||
|
||||
SortedMap<String, String> packageParams = new TreeMap<String, String>();
|
||||
packageParams.put("appid", wxMpConfigStorage.getAppId());
|
||||
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
|
||||
SortedMap<String, String> packageParams = new TreeMap<String, String>();
|
||||
packageParams.put("appid", wxMpConfigStorage.getAppId());
|
||||
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
|
||||
if (transactionId != null && !"".equals(transactionId.trim()))
|
||||
packageParams.put("transaction_id", transactionId);
|
||||
else if (outTradeNo != null && !"".equals(outTradeNo.trim()))
|
||||
packageParams.put("out_trade_no", outTradeNo);
|
||||
packageParams.put("nonce_str", nonce_str);
|
||||
else
|
||||
throw new IllegalArgumentException("Either 'transactionId' or 'outTradeNo' must be given.");
|
||||
packageParams.put("nonce_str", nonce_str);
|
||||
packageParams.put("sign", WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey()));
|
||||
|
||||
String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey());
|
||||
String xml = "<xml>" +
|
||||
"<appid>" + wxMpConfigStorage.getAppId() + "</appid>" +
|
||||
"<mch_id>" + wxMpConfigStorage.getPartnerId() + "</mch_id>" +
|
||||
"<transaction_id>" + transactionId + "</transaction_id>" +
|
||||
"<out_trade_no>" + outTradeNo + "</out_trade_no>" +
|
||||
"<nonce_str>" + nonce_str + "</nonce_str>" +
|
||||
"<sign>" + sign + "</sign>" +
|
||||
"</xml>";
|
||||
StringBuilder request = new StringBuilder("<xml>");
|
||||
for (Entry<String, String> para : packageParams.entrySet()) {
|
||||
request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey()));
|
||||
}
|
||||
request.append("</xml>");
|
||||
|
||||
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/orderquery");
|
||||
if (httpProxy != null) {
|
||||
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
|
||||
httpPost.setConfig(config);
|
||||
}
|
||||
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/orderquery");
|
||||
if (httpProxy != null) {
|
||||
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
|
||||
httpPost.setConfig(config);
|
||||
}
|
||||
|
||||
StringEntity entity = new StringEntity(xml, Consts.UTF_8);
|
||||
httpPost.setEntity(entity);
|
||||
try {
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.alias("xml", WxMpPayResult.class);
|
||||
WxMpPayResult wxMpPayResult = (WxMpPayResult) xstream.fromXML(responseContent);
|
||||
return wxMpPayResult;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new WxMpPayResult();
|
||||
StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8);
|
||||
httpPost.setEntity(entity);
|
||||
try {
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.alias("xml", WxMpPayResult.class);
|
||||
WxMpPayResult wxMpPayResult = (WxMpPayResult) xstream.fromXML(responseContent);
|
||||
return wxMpPayResult;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to query order due to IO exception.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -903,5 +969,49 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
return new WxMpPayCallback();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature) {
|
||||
return signature.equals(WxCryptUtil.createSign(kvm, wxMpConfigStorage.getPartnerKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxRedpackResult sendRedpack(Map<String, String> parameters) throws WxErrorException {
|
||||
String nonce_str = System.currentTimeMillis() + "";
|
||||
|
||||
SortedMap<String, String> packageParams = new TreeMap<String, String>(parameters);
|
||||
packageParams.put("wxappid", wxMpConfigStorage.getAppId());
|
||||
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
|
||||
packageParams.put("nonce_str", nonce_str);
|
||||
|
||||
String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey());
|
||||
packageParams.put("sign", sign);
|
||||
|
||||
StringBuilder request = new StringBuilder("<xml>");
|
||||
for (Entry<String, String> para : packageParams.entrySet()) {
|
||||
request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey()));
|
||||
}
|
||||
request.append("</xml>");
|
||||
|
||||
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");
|
||||
if (httpProxy != null) {
|
||||
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
|
||||
httpPost.setConfig(config);
|
||||
}
|
||||
|
||||
StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8);
|
||||
httpPost.setEntity(entity);
|
||||
try {
|
||||
CloseableHttpResponse response = getHttpclient().execute(httpPost);
|
||||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxRedpackResult.class);
|
||||
WxRedpackResult wxMpRedpackResult = (WxRedpackResult) xstream.fromXML(responseContent);
|
||||
return wxMpRedpackResult;
|
||||
} catch (IOException e) {
|
||||
log.error(MessageFormatter.format("The exception was happened when sending redpack '{}'.", request.toString()).getMessage(), e);
|
||||
WxError error = new WxError();
|
||||
error.setErrorCode(-1);
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import me.chanjar.weixin.mp.bean.WxMpXmlOutTransferCustomerServiceMessage;
|
||||
/**
|
||||
* 客服消息builder
|
||||
* <pre>
|
||||
* 用法: WxMpCustomMessage m = WxMpCustomMessage.TRANSFER_CUSTOMER_SERVICE().content(...).toUser(...).build();
|
||||
* 用法: WxMpCustomMessage m = WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE().content(...).toUser(...).build();
|
||||
* </pre>
|
||||
*
|
||||
* @author chanjarster
|
||||
@@ -25,4 +25,4 @@ public final class TransferCustomerServiceBuilder extends BaseBuilder<TransferCu
|
||||
m.setKfAccount(kfAccount);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package me.chanjar.weixin.mp.bean.result;
|
||||
|
||||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
|
||||
|
||||
public class WxMpOAuth2AccessToken implements Serializable {
|
||||
|
||||
private String accessToken;
|
||||
@@ -16,6 +16,8 @@ public class WxMpOAuth2AccessToken implements Serializable {
|
||||
|
||||
private String scope;
|
||||
|
||||
private String unionId;
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
@@ -56,6 +58,14 @@ public class WxMpOAuth2AccessToken implements Serializable {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
|
||||
public String getUnionId() {
|
||||
return unionId;
|
||||
}
|
||||
|
||||
public void setUnionId(String unionId) {
|
||||
this.unionId = unionId;
|
||||
}
|
||||
|
||||
public static WxMpOAuth2AccessToken fromJson(String json) {
|
||||
return WxMpGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class);
|
||||
}
|
||||
@@ -68,6 +78,7 @@ public class WxMpOAuth2AccessToken implements Serializable {
|
||||
", refreshToken='" + refreshToken + '\'' +
|
||||
", openId='" + openId + '\'' +
|
||||
", scope='" + scope + '\'' +
|
||||
", unionId='" + unionId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,203 +13,245 @@ import java.io.Serializable;
|
||||
* @author ukid
|
||||
*/
|
||||
public class WxMpPayResult implements Serializable {
|
||||
private String return_code;
|
||||
private String return_msg;
|
||||
private String appid;
|
||||
private String mch_id;
|
||||
private String nonce_str;
|
||||
private String sign;
|
||||
private String result_code;
|
||||
private String err_code;
|
||||
private String err_code_des;
|
||||
private String trade_state;
|
||||
private String device_info;
|
||||
private String openid;
|
||||
private String is_subscribe;
|
||||
private String trade_type;
|
||||
private String bank_type;
|
||||
private String total_fee;
|
||||
private String coupon_fee;
|
||||
private String fee_type;
|
||||
private String transaction_id;
|
||||
private String out_trade_no;
|
||||
private String attach;
|
||||
private String time_end;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -570934170727777190L;
|
||||
|
||||
private String return_code;
|
||||
private String return_msg;
|
||||
private String appid;
|
||||
private String mch_id;
|
||||
private String nonce_str;
|
||||
private String sign;
|
||||
private String result_code;
|
||||
private String err_code;
|
||||
private String err_code_des;
|
||||
private String trade_state;
|
||||
private String trade_state_desc;
|
||||
private String device_info;
|
||||
private String openid;
|
||||
private String is_subscribe;
|
||||
private String trade_type;
|
||||
private String bank_type;
|
||||
private String total_fee;
|
||||
private String coupon_fee;
|
||||
private String fee_type;
|
||||
private String transaction_id;
|
||||
private String out_trade_no;
|
||||
private String attach;
|
||||
private String time_end;
|
||||
|
||||
public String getReturn_code() {
|
||||
return return_code;
|
||||
}
|
||||
public String getReturn_code() {
|
||||
return return_code;
|
||||
}
|
||||
|
||||
public String getReturn_msg() {
|
||||
return return_msg;
|
||||
}
|
||||
public String getReturn_msg() {
|
||||
return return_msg;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public String getMch_id() {
|
||||
return mch_id;
|
||||
}
|
||||
public String getMch_id() {
|
||||
return mch_id;
|
||||
}
|
||||
|
||||
public String getNonce_str() {
|
||||
return nonce_str;
|
||||
}
|
||||
public String getNonce_str() {
|
||||
return nonce_str;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public String getResult_code() {
|
||||
return result_code;
|
||||
}
|
||||
public String getResult_code() {
|
||||
return result_code;
|
||||
}
|
||||
|
||||
public String getErr_code() {
|
||||
return err_code;
|
||||
}
|
||||
public String getErr_code() {
|
||||
return err_code;
|
||||
}
|
||||
|
||||
public String getErr_code_des() {
|
||||
return err_code_des;
|
||||
}
|
||||
public String getErr_code_des() {
|
||||
return err_code_des;
|
||||
}
|
||||
|
||||
public String getTrade_state() {
|
||||
return trade_state;
|
||||
}
|
||||
public String getTrade_state() {
|
||||
return trade_state;
|
||||
}
|
||||
|
||||
public String getDevice_info() {
|
||||
return device_info;
|
||||
}
|
||||
public String getDevice_info() {
|
||||
return device_info;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public String getIs_subscribe() {
|
||||
return is_subscribe;
|
||||
}
|
||||
public String getIs_subscribe() {
|
||||
return is_subscribe;
|
||||
}
|
||||
|
||||
public String getTrade_type() {
|
||||
return trade_type;
|
||||
}
|
||||
public String getTrade_type() {
|
||||
return trade_type;
|
||||
}
|
||||
|
||||
public String getBank_type() {
|
||||
return bank_type;
|
||||
}
|
||||
public String getBank_type() {
|
||||
return bank_type;
|
||||
}
|
||||
|
||||
public String getTotal_fee() {
|
||||
return total_fee;
|
||||
}
|
||||
public String getTotal_fee() {
|
||||
return total_fee;
|
||||
}
|
||||
|
||||
public String getCoupon_fee() {
|
||||
return coupon_fee;
|
||||
}
|
||||
public String getCoupon_fee() {
|
||||
return coupon_fee;
|
||||
}
|
||||
|
||||
public String getFee_type() {
|
||||
return fee_type;
|
||||
}
|
||||
public String getFee_type() {
|
||||
return fee_type;
|
||||
}
|
||||
|
||||
public String getTransaction_id() {
|
||||
return transaction_id;
|
||||
}
|
||||
public String getTransaction_id() {
|
||||
return transaction_id;
|
||||
}
|
||||
|
||||
public String getOut_trade_no() {
|
||||
return out_trade_no;
|
||||
}
|
||||
public String getOut_trade_no() {
|
||||
return out_trade_no;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public String getTime_end() {
|
||||
return time_end;
|
||||
}
|
||||
public String getTime_end() {
|
||||
return time_end;
|
||||
}
|
||||
|
||||
public void setReturn_code(String return_code) {
|
||||
this.return_code = return_code;
|
||||
}
|
||||
public void setReturn_code(String return_code) {
|
||||
this.return_code = return_code;
|
||||
}
|
||||
|
||||
public void setReturn_msg(String return_msg) {
|
||||
this.return_msg = return_msg;
|
||||
}
|
||||
public void setReturn_msg(String return_msg) {
|
||||
this.return_msg = return_msg;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public void setMch_id(String mch_id) {
|
||||
this.mch_id = mch_id;
|
||||
}
|
||||
public void setMch_id(String mch_id) {
|
||||
this.mch_id = mch_id;
|
||||
}
|
||||
|
||||
public void setNonce_str(String nonce_str) {
|
||||
this.nonce_str = nonce_str;
|
||||
}
|
||||
public void setNonce_str(String nonce_str) {
|
||||
this.nonce_str = nonce_str;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public void setResult_code(String result_code) {
|
||||
this.result_code = result_code;
|
||||
}
|
||||
public void setResult_code(String result_code) {
|
||||
this.result_code = result_code;
|
||||
}
|
||||
|
||||
public void setErr_code(String err_code) {
|
||||
this.err_code = err_code;
|
||||
}
|
||||
public void setErr_code(String err_code) {
|
||||
this.err_code = err_code;
|
||||
}
|
||||
|
||||
public void setErr_code_des(String err_code_des) {
|
||||
this.err_code_des = err_code_des;
|
||||
}
|
||||
public void setErr_code_des(String err_code_des) {
|
||||
this.err_code_des = err_code_des;
|
||||
}
|
||||
|
||||
public void setTrade_state(String trade_state) {
|
||||
this.trade_state = trade_state;
|
||||
}
|
||||
public void setTrade_state(String trade_state) {
|
||||
this.trade_state = trade_state;
|
||||
}
|
||||
|
||||
public void setDevice_info(String device_info) {
|
||||
this.device_info = device_info;
|
||||
}
|
||||
public void setDevice_info(String device_info) {
|
||||
this.device_info = device_info;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
public void setIs_subscribe(String is_subscribe) {
|
||||
this.is_subscribe = is_subscribe;
|
||||
}
|
||||
public void setIs_subscribe(String is_subscribe) {
|
||||
this.is_subscribe = is_subscribe;
|
||||
}
|
||||
|
||||
public void setTrade_type(String trade_type) {
|
||||
this.trade_type = trade_type;
|
||||
}
|
||||
public void setTrade_type(String trade_type) {
|
||||
this.trade_type = trade_type;
|
||||
}
|
||||
|
||||
public void setBank_type(String bank_type) {
|
||||
this.bank_type = bank_type;
|
||||
}
|
||||
public void setBank_type(String bank_type) {
|
||||
this.bank_type = bank_type;
|
||||
}
|
||||
|
||||
public void setTotal_fee(String total_fee) {
|
||||
this.total_fee = total_fee;
|
||||
}
|
||||
public void setTotal_fee(String total_fee) {
|
||||
this.total_fee = total_fee;
|
||||
}
|
||||
|
||||
public void setCoupon_fee(String coupon_fee) {
|
||||
this.coupon_fee = coupon_fee;
|
||||
}
|
||||
public void setCoupon_fee(String coupon_fee) {
|
||||
this.coupon_fee = coupon_fee;
|
||||
}
|
||||
|
||||
public void setFee_type(String fee_type) {
|
||||
this.fee_type = fee_type;
|
||||
}
|
||||
public void setFee_type(String fee_type) {
|
||||
this.fee_type = fee_type;
|
||||
}
|
||||
|
||||
public void setTransaction_id(String transaction_id) {
|
||||
this.transaction_id = transaction_id;
|
||||
}
|
||||
public void setTransaction_id(String transaction_id) {
|
||||
this.transaction_id = transaction_id;
|
||||
}
|
||||
|
||||
public void setOut_trade_no(String out_trade_no) {
|
||||
this.out_trade_no = out_trade_no;
|
||||
}
|
||||
public void setOut_trade_no(String out_trade_no) {
|
||||
this.out_trade_no = out_trade_no;
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public void setTime_end(String time_end) {
|
||||
this.time_end = time_end;
|
||||
}
|
||||
public void setTime_end(String time_end) {
|
||||
this.time_end = time_end;
|
||||
}
|
||||
|
||||
public String getTrade_state_desc() {
|
||||
return trade_state_desc;
|
||||
}
|
||||
|
||||
public void setTrade_state_desc(String trade_state_desc) {
|
||||
this.trade_state_desc = trade_state_desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WxMpPayResult{" +
|
||||
"return_code=" + return_code +
|
||||
", return_msg='" + return_msg + '\'' +
|
||||
", appid='" + appid + '\'' +
|
||||
", mch_id='" + mch_id + '\'' +
|
||||
", nonce_str='" + nonce_str + '\'' +
|
||||
", sign='" + sign + '\'' +
|
||||
", result_code='" + result_code + '\'' +
|
||||
", err_code='" + err_code + '\'' +
|
||||
", err_code_des='" + err_code_des + '\'' +
|
||||
", trade_state=" + trade_state +
|
||||
", trade_state_desc=" + trade_state_desc +
|
||||
", device_info='" + device_info + '\'' +
|
||||
", openid='" + openid + '\'' +
|
||||
", is_subscribe='" + is_subscribe + '\'' +
|
||||
", trade_type='" + trade_type + '\'' +
|
||||
", bank_type='" + bank_type + '\'' +
|
||||
", total_fee='" + total_fee + '\'' +
|
||||
", coupon_fee='" + coupon_fee + '\'' +
|
||||
", fee_type='" + fee_type + '\'' +
|
||||
", transaction_id='" + transaction_id + '\'' +
|
||||
", out_trade_no='" + out_trade_no + '\'' +
|
||||
", attach='" + attach + '\'' +
|
||||
", time_end='" + time_end + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ public class WxMpPrepayIdResult implements Serializable {
|
||||
private String result_code;
|
||||
private String prepay_id;
|
||||
private String trade_type;
|
||||
private String err_code;
|
||||
private String err_code_des;
|
||||
private String code_url;
|
||||
|
||||
public String getReturn_code() {
|
||||
return return_code;
|
||||
@@ -94,4 +97,28 @@ public class WxMpPrepayIdResult implements Serializable {
|
||||
public void setTrade_type(String trade_type) {
|
||||
this.trade_type = trade_type;
|
||||
}
|
||||
|
||||
public String getErr_code() {
|
||||
return err_code;
|
||||
}
|
||||
|
||||
public void setErr_code(String err_code) {
|
||||
this.err_code = err_code;
|
||||
}
|
||||
|
||||
public String getErr_code_des() {
|
||||
return err_code_des;
|
||||
}
|
||||
|
||||
public void setErr_code_des(String err_code_des) {
|
||||
this.err_code_des = err_code_des;
|
||||
}
|
||||
|
||||
public String getCode_url() {
|
||||
return code_url;
|
||||
}
|
||||
|
||||
public void setCode_url(String code_url) {
|
||||
this.code_url = code_url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package me.chanjar.weixin.mp.bean.result;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 向微信用户个人发现金红包返回结果
|
||||
* https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5
|
||||
* @author kane
|
||||
*
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class WxRedpackResult implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4837415036337132073L;
|
||||
|
||||
@XStreamAlias("return_code")
|
||||
String returnCode;
|
||||
@XStreamAlias("return_msg")
|
||||
String returnMsg;
|
||||
@XStreamAlias("sign")
|
||||
String sign;
|
||||
@XStreamAlias("result_code")
|
||||
String resultCode;
|
||||
|
||||
@XStreamAlias("err_code")
|
||||
String errCode;
|
||||
@XStreamAlias("err_code_des")
|
||||
String errCodeDes;
|
||||
@XStreamAlias("mch_billno")
|
||||
String mchBillno;
|
||||
@XStreamAlias("mch_id")
|
||||
String mchId;
|
||||
@XStreamAlias("wxappid")
|
||||
String wxappid;
|
||||
@XStreamAlias("re_openid")
|
||||
String reOpenid;
|
||||
@XStreamAlias("total_amount")
|
||||
int totalAmount;
|
||||
@XStreamAlias("send_time")
|
||||
String sendTime;
|
||||
@XStreamAlias("send_listid")
|
||||
String sendListid;
|
||||
|
||||
public String getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
public String getErrCodeDes() {
|
||||
return errCodeDes;
|
||||
}
|
||||
|
||||
public String getReturnCode() {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
public String getReturnMsg() {
|
||||
return returnMsg;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public String getResultCode() {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
public String getMchBillno() {
|
||||
return mchBillno;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public String getWxappid() {
|
||||
return wxappid;
|
||||
}
|
||||
|
||||
public String getReOpenid() {
|
||||
return reOpenid;
|
||||
}
|
||||
|
||||
public int getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
public String getSendTime() {
|
||||
return sendTime;
|
||||
}
|
||||
|
||||
public String getSendListid() {
|
||||
return sendListid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WxRedpackResult{" +
|
||||
"returnCode=" + returnCode +
|
||||
", returnMsg=" + returnMsg +
|
||||
", sign=" + sign +
|
||||
", errCode=" + errCode +
|
||||
", errCodeDes=" + errCodeDes +
|
||||
", mchBillno=" + mchBillno +
|
||||
", mchId=" + mchId +
|
||||
", wxappid=" + wxappid +
|
||||
", reOpenid=" + reOpenid +
|
||||
", totalAmount=" + totalAmount +
|
||||
", sendTime=" + sendTime +
|
||||
", sendListid=" + sendListid +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.HttpMultipartMode;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.entity.mime.content.InputStreamBody;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
@@ -36,7 +37,9 @@ public class MaterialUploadRequestExecutor implements RequestExecutor<WxMpMateri
|
||||
}
|
||||
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
|
||||
multipartEntityBuilder.addPart("media", new InputStreamBody(bufferedInputStream, material.getName()));
|
||||
multipartEntityBuilder
|
||||
.addPart("media", new InputStreamBody(bufferedInputStream, material.getName()))
|
||||
.setMode(HttpMultipartMode.RFC6532);
|
||||
Map<String, String> form = material.getForm();
|
||||
if (material.getForm() != null) {
|
||||
multipartEntityBuilder.addTextBody("description", WxGsonBuilder.create().toJson(form));
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package me.chanjar.weixin.mp.util.json;
|
||||
|
||||
import com.google.gson.*;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import me.chanjar.weixin.common.util.json.GsonHelper;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class WxMpOAuth2AccessTokenAdapter implements JsonDeserializer<WxMpOAuth2AccessToken> {
|
||||
|
||||
public WxMpOAuth2AccessToken deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
@@ -28,6 +33,9 @@ public class WxMpOAuth2AccessTokenAdapter implements JsonDeserializer<WxMpOAuth2
|
||||
if (accessTokenJsonObject.get("scope") != null && !accessTokenJsonObject.get("scope").isJsonNull()) {
|
||||
accessToken.setScope(GsonHelper.getAsString(accessTokenJsonObject.get("scope")));
|
||||
}
|
||||
if (accessTokenJsonObject.get("unionid") != null && !accessTokenJsonObject.get("unionid").isJsonNull()) {
|
||||
accessToken.setUnionId(GsonHelper.getAsString(accessTokenJsonObject.get("unionid")));
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ public class WxMpUserGsonAdapter implements JsonDeserializer<WxMpUser> {
|
||||
public WxMpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObject o = json.getAsJsonObject();
|
||||
WxMpUser wxMpUser = new WxMpUser();
|
||||
wxMpUser.setSubscribe(new Integer(0).equals(GsonHelper.getInteger(o, "subscribe")) ? false : true);
|
||||
Integer subscribe = GsonHelper.getInteger(o, "subscribe");
|
||||
if (subscribe != null) {
|
||||
wxMpUser.setSubscribe(new Integer(0).equals(subscribe) ? false : true);
|
||||
}
|
||||
wxMpUser.setCity(GsonHelper.getString(o, "city"));
|
||||
wxMpUser.setCountry(GsonHelper.getString(o, "country"));
|
||||
wxMpUser.setHeadImgUrl(GsonHelper.getString(o, "headimgurl"));
|
||||
|
||||
@@ -22,7 +22,7 @@ public class WxUserListGsonAdapter implements JsonDeserializer<WxMpUserList> {
|
||||
wxMpUserList.setTotal(GsonHelper.getInteger(o, "total"));
|
||||
wxMpUserList.setCount(GsonHelper.getInteger(o, "count"));
|
||||
wxMpUserList.setNextOpenId(GsonHelper.getString(o, "next_openid"));
|
||||
if (!o.get("data").isJsonNull() && !o.get("data").getAsJsonObject().get("openid").isJsonNull()) {
|
||||
if (o.get("data") != null && !o.get("data").isJsonNull() && !o.get("data").getAsJsonObject().get("openid").isJsonNull()) {
|
||||
JsonArray data = o.get("data").getAsJsonObject().get("openid").getAsJsonArray();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
wxMpUserList.getOpenIds().add(GsonHelper.getAsString(data.get(i)));
|
||||
|
||||
@@ -51,6 +51,8 @@ public class XStreamTransformer {
|
||||
map.put(WxMpXmlOutImageMessage.class, config_WxMpXmlOutImageMessage());
|
||||
map.put(WxMpXmlOutVideoMessage.class, config_WxMpXmlOutVideoMessage());
|
||||
map.put(WxMpXmlOutVoiceMessage.class, config_WxMpXmlOutVoiceMessage());
|
||||
map.put(WxMpXmlOutTransferCustomerServiceMessage.class, config_WxMpXmlOutTransferCustomerServiceMessage());
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -111,4 +113,12 @@ public class XStreamTransformer {
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream config_WxMpXmlOutTransferCustomerServiceMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxMpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxMpXmlOutTransferCustomerServiceMessage.class);
|
||||
xstream.processAnnotations(WxMpXmlOutTransferCustomerServiceMessage.TransInfo.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package me.chanjar.weixin.mp.bean;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.mp.bean.result.WxRedpackResult;
|
||||
|
||||
public class WxRedpackResultTest {
|
||||
|
||||
private XStream xstream;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxRedpackResult.class);
|
||||
}
|
||||
|
||||
@Test public void loadSuccessResult() {
|
||||
final String successSample = "<xml>\n" +
|
||||
"<return_code><![CDATA[SUCCESS]]></return_code>\n" +
|
||||
"<return_msg><![CDATA[发放成功.]]></return_msg>\n" +
|
||||
"<result_code><![CDATA[SUCCESS]]></result_code>\n" +
|
||||
"<err_code><![CDATA[0]]></err_code>\n" +
|
||||
"<err_code_des><![CDATA[发放成功.]]></err_code_des>\n" +
|
||||
"<mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno>\n" +
|
||||
"<mch_id>10010404</mch_id>\n" +
|
||||
"<wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid>\n" +
|
||||
"<re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid>\n" +
|
||||
"<total_amount>1</total_amount>\n" +
|
||||
"<send_listid>100000000020150520314766074200</send_listid>\n" +
|
||||
"<send_time>20150520102602</send_time>\n" +
|
||||
"</xml>";
|
||||
WxRedpackResult wxMpRedpackResult = (WxRedpackResult) xstream.fromXML(successSample);
|
||||
assertEquals("SUCCESS", wxMpRedpackResult.getReturnCode());
|
||||
assertEquals("SUCCESS", wxMpRedpackResult.getResultCode());
|
||||
assertEquals("20150520102602", wxMpRedpackResult.getSendTime());
|
||||
}
|
||||
|
||||
@Test public void loadFailureResult() {
|
||||
final String failureSample = "<xml>\n" +
|
||||
"<return_code><![CDATA[FAIL]]></return_code>\n" +
|
||||
"<return_msg><![CDATA[系统繁忙,请稍后再试.]]></return_msg>\n" +
|
||||
"<result_code><![CDATA[FAIL]]></result_code>\n" +
|
||||
"<err_code><![CDATA[268458547]]></err_code>\n" +
|
||||
"<err_code_des><![CDATA[系统繁忙,请稍后再试.]]></err_code_des>\n" +
|
||||
"<mch_billno><![CDATA[0010010404201411170000046542]]></mch_billno>\n" +
|
||||
"<mch_id>10010404</mch_id>\n" +
|
||||
"<wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid>\n" +
|
||||
"<re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid>\n" +
|
||||
"<total_amount>1</total_amount>\n" +
|
||||
"</xml>";
|
||||
WxRedpackResult wxMpRedpackResult = (WxRedpackResult) xstream.fromXML(failureSample);
|
||||
assertEquals("FAIL", wxMpRedpackResult.getReturnCode());
|
||||
assertEquals("FAIL", wxMpRedpackResult.getResultCode());
|
||||
assertEquals("onqOjjmM1tad-3ROpncN-yUfa6uI", wxMpRedpackResult.getReOpenid());
|
||||
assertEquals(1, wxMpRedpackResult.getTotalAmount());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user