org.apache.httpcomponents
httpmime
@@ -296,10 +319,8 @@
org.apache.maven.plugins
maven-compiler-plugin
- 2.3.2
+ 3.6.0
- 1.7
- 1.7
UTF-8
diff --git a/weixin-java-common/build.gradle b/weixin-java-common/build.gradle
index 07b5036a..71800493 100644
--- a/weixin-java-common/build.gradle
+++ b/weixin-java-common/build.gradle
@@ -6,7 +6,7 @@ dependencies {
testCompile group: 'org.testng', name: 'testng', version:'6.8.7'
testCompile group: 'org.mockito', name: 'mockito-all', version:'1.9.5'
testCompile group: 'com.google.inject', name: 'guice', version:'3.0'
- testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version:'9.3.0.M0'
- testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version:'9.3.0.M0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version:'9.3.0.RC0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version:'9.3.0.RC0'
}
test.useTestNG()
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index e5d5d73a..329da5a2 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
weixin-java-parent
- 2.3.0
+ 2.4.0
weixin-java-common
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
index 3bfd1175..3553c5f6 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
@@ -18,8 +18,13 @@ public class WxConsts {
public static final String XML_MSG_LOCATION = "location";
public static final String XML_MSG_LINK = "link";
public static final String XML_MSG_EVENT = "event";
+ public static final String XML_MSG_DEVICE_TEXT = "device_text";
+ public static final String XML_MSG_DEVICE_EVENT = "device_event";
+ public static final String XML_MSG_DEVICE_STATUS = "device_status";
+ public static final String XML_MSG_HARDWARE = "hardware";
public static final String XML_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
+
///////////////////////
// 主动发送消息(即客服消息)的消息类型
///////////////////////
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java
index 6b43ed06..4e61a465 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java
@@ -1,5 +1,8 @@
package me.chanjar.weixin.common.bean.menu;
+import me.chanjar.weixin.common.util.ToStringUtils;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
@@ -7,11 +10,8 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
-import me.chanjar.weixin.common.bean.menu.WxMenuButton;
-import me.chanjar.weixin.common.util.json.WxGsonBuilder;
-
/**
- * 企业号菜单
+ * 菜单(公众号和企业号共用的)
*
* @author Daniel Qian
*/
@@ -61,9 +61,7 @@ public class WxMenu implements Serializable {
@Override
public String toString() {
- return "WxMenu{" +
- "buttons=" + this.buttons +
- '}';
+ return ToStringUtils.toSimpleString(this);
}
}
diff --git a/weixin-java-cp/build.gradle b/weixin-java-cp/build.gradle
index f58703ca..85d7c4bb 100644
--- a/weixin-java-cp/build.gradle
+++ b/weixin-java-cp/build.gradle
@@ -6,7 +6,7 @@ dependencies {
testCompile group: 'org.testng', name: 'testng', version:'6.8.7'
testCompile group: 'org.mockito', name: 'mockito-all', version:'1.9.5'
testCompile group: 'com.google.inject', name: 'guice', version:'3.0'
- testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version:'9.3.0.M0'
- testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version:'9.3.0.M0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version:'9.3.0.RC0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version:'9.3.0.RC0'
}
test.useTestNG()
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index e7fbd255..6b7c1665 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
weixin-java-parent
- 2.3.0
+ 2.4.0
weixin-java-cp
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
index b334b85b..eb1e57ca 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
@@ -45,7 +45,7 @@ public interface WxCpConfigStorage {
String getCorpSecret();
- String getAgentId();
+ Integer getAgentId();
String getToken();
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
index fb7bacff..867dd6bb 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
@@ -19,7 +19,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
protected volatile String token;
protected volatile String accessToken;
protected volatile String aesKey;
- protected volatile String agentId;
+ protected volatile Integer agentId;
protected volatile long expiresTime;
protected volatile String oauth2redirectUri;
@@ -146,11 +146,11 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
}
@Override
- public String getAgentId() {
+ public Integer getAgentId() {
return this.agentId;
}
- public void setAgentId(String agentId) {
+ public void setAgentId(Integer agentId) {
this.agentId = agentId;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpJedisConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpJedisConfigStorage.java
index 5209479f..92513965 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpJedisConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpJedisConfigStorage.java
@@ -1,267 +1,259 @@
-package me.chanjar.weixin.cp.api;
-
-import java.io.File;
-
-import me.chanjar.weixin.common.bean.WxAccessToken;
-import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
-import redis.clients.jedis.Jedis;
-import redis.clients.jedis.JedisPool;
-
-/**
- * Jedis client implementor for wechat config storage
- *
- * @author gaigeshen
- */
-public class WxCpJedisConfigStorage implements WxCpConfigStorage {
-
- /* Redis keys here */
- private static final String ACCESS_TOKEN_KEY = "WX_CP_ACCESS_TOKEN";
- private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME";
- private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET";
- private static final String JS_API_TICKET_EXPIRES_TIME_KEY = "WX_CP_JS_API_TICKET_EXPIRES_TIME";
-
- private volatile String corpId;
- private volatile String corpSecret;
-
- private volatile String token;
- private volatile String aesKey;
- private volatile String agentId;
-
- private volatile String oauth2redirectUri;
-
- private volatile String httpProxyHost;
- private volatile int httpProxyPort;
- private volatile String httpProxyUsername;
- private volatile String httpProxyPassword;
-
- private volatile File tmpDirFile;
-
- private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
-
- /* Redis clients pool */
- private final JedisPool jedisPool;
-
- public WxCpJedisConfigStorage(String host, int port) {
- this.jedisPool = new JedisPool(host, port);
- }
-
- /**
- *
- * This method will be destroy jedis pool
- */
- public void destroy() {
- this.jedisPool.destroy();
- }
-
- @Override
- public String getAccessToken() {
- try (Jedis jedis = this.jedisPool.getResource()) {
- return jedis.get(ACCESS_TOKEN_KEY);
- }
- }
-
- @Override
- public boolean isAccessTokenExpired() {
- try (Jedis jedis = this.jedisPool.getResource()) {
- String expiresTimeStr = jedis.get(ACCESS_TOKEN_EXPIRES_TIME_KEY);
-
- if (expiresTimeStr != null) {
- Long expiresTime = Long.parseLong(expiresTimeStr);
- return System.currentTimeMillis() > expiresTime;
- }
-
- return true;
-
- }
- }
-
- @Override
- public void expireAccessToken() {
- try (Jedis jedis = this.jedisPool.getResource()) {
- jedis.set(ACCESS_TOKEN_EXPIRES_TIME_KEY, "0");
- }
- }
-
- @Override
- public synchronized void updateAccessToken(WxAccessToken accessToken) {
- this.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
- }
-
- @Override
- public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
- try (Jedis jedis = this.jedisPool.getResource()) {
- jedis.set(ACCESS_TOKEN_KEY, accessToken);
-
- jedis.set(ACCESS_TOKEN_EXPIRES_TIME_KEY,
- (System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L) + "");
- }
- }
-
- @Override
- public String getJsapiTicket() {
- try (Jedis jedis = this.jedisPool.getResource()) {
- return jedis.get(JS_API_TICKET_KEY);
- }
- }
-
- @Override
- public boolean isJsapiTicketExpired() {
-
- try (Jedis jedis = this.jedisPool.getResource()) {
- String expiresTimeStr = jedis.get(JS_API_TICKET_EXPIRES_TIME_KEY);
-
- if (expiresTimeStr != null) {
- Long expiresTime = Long.parseLong(expiresTimeStr);
- return System.currentTimeMillis() > expiresTime;
- }
-
- return true;
-
- }
- }
-
- @Override
- public void expireJsapiTicket() {
- try (Jedis jedis = this.jedisPool.getResource()) {
- jedis.set(JS_API_TICKET_EXPIRES_TIME_KEY, "0");
- }
- }
-
- @Override
- public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
-
- try (Jedis jedis = this.jedisPool.getResource()) {
- jedis.set(JS_API_TICKET_KEY, jsapiTicket);
-
- jedis.set(JS_API_TICKET_EXPIRES_TIME_KEY,
- (System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L + ""));
- }
-
- }
-
- @Override
- public String getCorpId() {
- return this.corpId;
- }
-
- @Override
- public String getCorpSecret() {
- return this.corpSecret;
- }
-
- @Override
- public String getAgentId() {
- return this.agentId;
- }
-
- @Override
- public String getToken() {
- return this.token;
- }
-
- @Override
- public String getAesKey() {
- return this.aesKey;
- }
-
- @Override
- public long getExpiresTime() {
- try (Jedis jedis = this.jedisPool.getResource()) {
- String expiresTimeStr = jedis.get(ACCESS_TOKEN_EXPIRES_TIME_KEY);
-
- if (expiresTimeStr != null) {
- Long expiresTime = Long.parseLong(expiresTimeStr);
- return expiresTime;
- }
-
- return 0L;
-
- }
- }
-
- @Override
- public String getOauth2redirectUri() {
- return this.oauth2redirectUri;
- }
-
- @Override
- public String getHttpProxyHost() {
- return this.httpProxyHost;
- }
-
- @Override
- public int getHttpProxyPort() {
- return this.httpProxyPort;
- }
-
- @Override
- public String getHttpProxyUsername() {
- return this.httpProxyUsername;
- }
-
- @Override
- public String getHttpProxyPassword() {
- return this.httpProxyPassword;
- }
-
- @Override
- public File getTmpDirFile() {
- return this.tmpDirFile;
- }
-
- @Override
- public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
- return this.apacheHttpClientBuilder;
- }
-
- public void setCorpId(String corpId) {
- this.corpId = corpId;
- }
-
- public void setCorpSecret(String corpSecret) {
- this.corpSecret = corpSecret;
- }
-
- public void setToken(String token) {
- this.token = token;
- }
-
- public void setAesKey(String aesKey) {
- this.aesKey = aesKey;
- }
-
- public void setAgentId(String agentId) {
- this.agentId = agentId;
- }
-
- // ============================ Setters below
-
- public void setOauth2redirectUri(String oauth2redirectUri) {
- this.oauth2redirectUri = oauth2redirectUri;
- }
-
- public void setHttpProxyHost(String httpProxyHost) {
- this.httpProxyHost = httpProxyHost;
- }
-
- public void setHttpProxyPort(int httpProxyPort) {
- this.httpProxyPort = httpProxyPort;
- }
-
- public void setHttpProxyUsername(String httpProxyUsername) {
- this.httpProxyUsername = httpProxyUsername;
- }
-
- public void setHttpProxyPassword(String httpProxyPassword) {
- this.httpProxyPassword = httpProxyPassword;
- }
-
- public void setTmpDirFile(File tmpDirFile) {
- this.tmpDirFile = tmpDirFile;
- }
-
- public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
- this.apacheHttpClientBuilder = apacheHttpClientBuilder;
- }
-
-}
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+
+import java.io.File;
+
+/**
+ * Jedis client implementor for wechat config storage
+ *
+ * @author gaigeshen
+ */
+public class WxCpJedisConfigStorage implements WxCpConfigStorage {
+
+ /* Redis keys here */
+ private static final String ACCESS_TOKEN_KEY = "WX_CP_ACCESS_TOKEN";
+ private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME";
+ private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET";
+ private static final String JS_API_TICKET_EXPIRES_TIME_KEY = "WX_CP_JS_API_TICKET_EXPIRES_TIME";
+ /* Redis clients pool */
+ private final JedisPool jedisPool;
+ private volatile String corpId;
+ private volatile String corpSecret;
+ private volatile String token;
+ private volatile String aesKey;
+ private volatile Integer agentId;
+ private volatile String oauth2redirectUri;
+ private volatile String httpProxyHost;
+ private volatile int httpProxyPort;
+ private volatile String httpProxyUsername;
+ private volatile String httpProxyPassword;
+ private volatile File tmpDirFile;
+ private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
+
+ public WxCpJedisConfigStorage(String host, int port) {
+ this.jedisPool = new JedisPool(host, port);
+ }
+
+ /**
+ * This method will be destroy jedis pool
+ */
+ public void destroy() {
+ this.jedisPool.destroy();
+ }
+
+ @Override
+ public String getAccessToken() {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ return jedis.get(ACCESS_TOKEN_KEY);
+ }
+ }
+
+ @Override
+ public boolean isAccessTokenExpired() {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ String expiresTimeStr = jedis.get(ACCESS_TOKEN_EXPIRES_TIME_KEY);
+
+ if (expiresTimeStr != null) {
+ Long expiresTime = Long.parseLong(expiresTimeStr);
+ return System.currentTimeMillis() > expiresTime;
+ }
+
+ return true;
+
+ }
+ }
+
+ @Override
+ public void expireAccessToken() {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ jedis.set(ACCESS_TOKEN_EXPIRES_TIME_KEY, "0");
+ }
+ }
+
+ @Override
+ public synchronized void updateAccessToken(WxAccessToken accessToken) {
+ this.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+ }
+
+ @Override
+ public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ jedis.set(ACCESS_TOKEN_KEY, accessToken);
+
+ jedis.set(ACCESS_TOKEN_EXPIRES_TIME_KEY,
+ (System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L) + "");
+ }
+ }
+
+ @Override
+ public String getJsapiTicket() {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ return jedis.get(JS_API_TICKET_KEY);
+ }
+ }
+
+ @Override
+ public boolean isJsapiTicketExpired() {
+
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ String expiresTimeStr = jedis.get(JS_API_TICKET_EXPIRES_TIME_KEY);
+
+ if (expiresTimeStr != null) {
+ Long expiresTime = Long.parseLong(expiresTimeStr);
+ return System.currentTimeMillis() > expiresTime;
+ }
+
+ return true;
+
+ }
+ }
+
+ @Override
+ public void expireJsapiTicket() {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ jedis.set(JS_API_TICKET_EXPIRES_TIME_KEY, "0");
+ }
+ }
+
+ @Override
+ public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ jedis.set(JS_API_TICKET_KEY, jsapiTicket);
+
+ jedis.set(JS_API_TICKET_EXPIRES_TIME_KEY,
+ (System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L + ""));
+ }
+
+ }
+
+ @Override
+ public String getCorpId() {
+ return this.corpId;
+ }
+
+ public void setCorpId(String corpId) {
+ this.corpId = corpId;
+ }
+
+ @Override
+ public String getCorpSecret() {
+ return this.corpSecret;
+ }
+
+ public void setCorpSecret(String corpSecret) {
+ this.corpSecret = corpSecret;
+ }
+
+ @Override
+ public Integer getAgentId() {
+ return this.agentId;
+ }
+
+ public void setAgentId(Integer agentId) {
+ this.agentId = agentId;
+ }
+
+ @Override
+ public String getToken() {
+ return this.token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ @Override
+ public String getAesKey() {
+ return this.aesKey;
+ }
+
+ public void setAesKey(String aesKey) {
+ this.aesKey = aesKey;
+ }
+
+ @Override
+ public long getExpiresTime() {
+ try (Jedis jedis = this.jedisPool.getResource()) {
+ String expiresTimeStr = jedis.get(ACCESS_TOKEN_EXPIRES_TIME_KEY);
+
+ if (expiresTimeStr != null) {
+ Long expiresTime = Long.parseLong(expiresTimeStr);
+ return expiresTime;
+ }
+
+ return 0L;
+
+ }
+ }
+
+ @Override
+ public String getOauth2redirectUri() {
+ return this.oauth2redirectUri;
+ }
+
+ public void setOauth2redirectUri(String oauth2redirectUri) {
+ this.oauth2redirectUri = oauth2redirectUri;
+ }
+
+ @Override
+ public String getHttpProxyHost() {
+ return this.httpProxyHost;
+ }
+
+ public void setHttpProxyHost(String httpProxyHost) {
+ this.httpProxyHost = httpProxyHost;
+ }
+
+ @Override
+ public int getHttpProxyPort() {
+ return this.httpProxyPort;
+ }
+
+ public void setHttpProxyPort(int httpProxyPort) {
+ this.httpProxyPort = httpProxyPort;
+ }
+
+ @Override
+ public String getHttpProxyUsername() {
+ return this.httpProxyUsername;
+ }
+
+ // ============================ Setters below
+
+ public void setHttpProxyUsername(String httpProxyUsername) {
+ this.httpProxyUsername = httpProxyUsername;
+ }
+
+ @Override
+ public String getHttpProxyPassword() {
+ return this.httpProxyPassword;
+ }
+
+ public void setHttpProxyPassword(String httpProxyPassword) {
+ this.httpProxyPassword = httpProxyPassword;
+ }
+
+ @Override
+ public File getTmpDirFile() {
+ return this.tmpDirFile;
+ }
+
+ public void setTmpDirFile(File tmpDirFile) {
+ this.tmpDirFile = tmpDirFile;
+ }
+
+ @Override
+ public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
+ return this.apacheHttpClientBuilder;
+ }
+
+ public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
+ this.apacheHttpClientBuilder = apacheHttpClientBuilder;
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
index 6d4a8a97..da18e28e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
@@ -163,12 +163,12 @@ public class WxCpMessageRouter {
// 返回最后一个非异步的rule的执行结果
if (rule.isAsync()) {
futures.add(
- this.executorService.submit(new Runnable() {
- @Override
- public void run() {
- rule.service(wxMessage, WxCpMessageRouter.this.wxCpService, WxCpMessageRouter.this.sessionManager, WxCpMessageRouter.this.exceptionHandler);
- }
- })
+ this.executorService.submit(new Runnable() {
+ @Override
+ public void run() {
+ rule.service(wxMessage, WxCpMessageRouter.this.wxCpService, WxCpMessageRouter.this.sessionManager, WxCpMessageRouter.this.exceptionHandler);
+ }
+ })
);
} else {
res = rule.service(wxMessage, this.wxCpService, this.sessionManager, this.exceptionHandler);
@@ -205,10 +205,10 @@ public class WxCpMessageRouter {
String messageId = "";
if (wxMessage.getMsgId() == null) {
messageId = String.valueOf(wxMessage.getCreateTime())
- + "-" + String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId())
- + "-" + wxMessage.getFromUserName()
- + "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey())
- + "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent())
+ + "-" + String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId())
+ + "-" + wxMessage.getFromUserName()
+ + "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey())
+ + "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent())
;
} else {
messageId = String.valueOf(wxMessage.getMsgId());
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouterRule.java
index c81f045f..7bd332ad 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouterRule.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouterRule.java
@@ -202,24 +202,24 @@ public class WxCpMessageRouterRule {
protected boolean test(WxCpXmlMessage wxMessage) {
return
- (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName()))
- &&
- (this.agentId == null || this.agentId.equals(wxMessage.getAgentId()))
- &&
- (this.msgType == null || this.msgType.equals(wxMessage.getMsgType()))
- &&
- (this.event == null || this.event.equals(wxMessage.getEvent()))
- &&
- (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey()))
- &&
- (this.content == null || this.content
- .equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim()))
- &&
- (this.rContent == null || Pattern
- .matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim()))
- &&
- (this.matcher == null || this.matcher.match(wxMessage))
- ;
+ (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName()))
+ &&
+ (this.agentId == null || this.agentId.equals(wxMessage.getAgentId()))
+ &&
+ (this.msgType == null || this.msgType.equals(wxMessage.getMsgType()))
+ &&
+ (this.event == null || this.event.equals(wxMessage.getEvent()))
+ &&
+ (this.eventKey == null || this.eventKey.equals(wxMessage.getEventKey()))
+ &&
+ (this.content == null || this.content
+ .equals(wxMessage.getContent() == null ? null : wxMessage.getContent().trim()))
+ &&
+ (this.rContent == null || Pattern
+ .matches(this.rContent, wxMessage.getContent() == null ? "" : wxMessage.getContent().trim()))
+ &&
+ (this.matcher == null || this.matcher.match(wxMessage))
+ ;
}
/**
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
index e6f8f2ad..b5bf50c9 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
@@ -160,7 +160,7 @@ public interface WxCpService {
*
* @param menu
* @throws WxErrorException
- * @see #menuCreate(String, me.chanjar.weixin.common.bean.menu.WxMenu)
+ * @see #menuCreate(Integer, WxMenu)
*/
void menuCreate(WxMenu menu) throws WxErrorException;
@@ -177,7 +177,7 @@ public interface WxCpService {
* @throws WxErrorException
* @see #menuCreate(me.chanjar.weixin.common.bean.menu.WxMenu)
*/
- void menuCreate(String agentId, WxMenu menu) throws WxErrorException;
+ void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException;
/**
*
@@ -188,7 +188,7 @@ public interface WxCpService {
*
*
* @throws WxErrorException
- * @see #menuDelete(String)
+ * @see #menuDelete(Integer)
*/
void menuDelete() throws WxErrorException;
@@ -204,7 +204,7 @@ public interface WxCpService {
* @throws WxErrorException
* @see #menuDelete()
*/
- void menuDelete(String agentId) throws WxErrorException;
+ void menuDelete(Integer agentId) throws WxErrorException;
/**
*
@@ -215,7 +215,7 @@ public interface WxCpService {
*
*
* @throws WxErrorException
- * @see #menuGet(String)
+ * @see #menuGet(Integer)
*/
WxMenu menuGet() throws WxErrorException;
@@ -231,7 +231,7 @@ public interface WxCpService {
* @throws WxErrorException
* @see #menuGet()
*/
- WxMenu menuGet(String agentId) throws WxErrorException;
+ WxMenu menuGet(Integer agentId) throws WxErrorException;
/**
*
@@ -396,12 +396,12 @@ public interface WxCpService {
*
* 构造oauth2授权的url连接
*
- *
+ *
* @param state
* @return url
*/
String oauth2buildAuthorizationUrl(String state);
-
+
/**
*
* 构造oauth2授权的url连接
@@ -425,7 +425,7 @@ public interface WxCpService {
*
* @param code
* @return [userid, deviceid]
- * @see #oauth2getUserInfo(String, String)
+ * @see #oauth2getUserInfo(Integer, String)
*/
String[] oauth2getUserInfo(String code) throws WxErrorException;
@@ -443,7 +443,7 @@ public interface WxCpService {
* @return [userid, deviceid]
* @see #oauth2getUserInfo(String)
*/
- String[] oauth2getUserInfo(String agentId, String code) throws WxErrorException;
+ String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException;
/**
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
index b044b468..d44bbf5f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
@@ -23,7 +23,6 @@ import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
-import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
@@ -69,7 +68,7 @@ public class WxCpServiceImpl implements WxCpService {
public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) {
try {
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data)
- .equals(msgSignature);
+ .equals(msgSignature);
} catch (Exception e) {
return false;
}
@@ -95,18 +94,18 @@ public class WxCpServiceImpl implements WxCpService {
synchronized (this.globalAccessTokenRefreshLock) {
if (this.configStorage.isAccessTokenExpired()) {
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
- + "&corpid=" + this.configStorage.getCorpId()
- + "&corpsecret=" + this.configStorage.getCorpSecret();
+ + "&corpid=" + this.configStorage.getCorpId()
+ + "&corpsecret=" + this.configStorage.getCorpSecret();
try {
HttpGet httpGet = new HttpGet(url);
if (this.httpProxy != null) {
RequestConfig config = RequestConfig.custom()
- .setProxy(this.httpProxy).build();
+ .setProxy(this.httpProxy).build();
httpGet.setConfig(config);
}
String resultContent = null;
try (CloseableHttpClient httpclient = getHttpclient();
- CloseableHttpResponse response = httpclient.execute(httpGet)) {
+ CloseableHttpResponse response = httpclient.execute(httpGet)) {
resultContent = new BasicResponseHandler().handleResponse(response);
} finally {
httpGet.releaseConnection();
@@ -117,9 +116,7 @@ public class WxCpServiceImpl implements WxCpService {
}
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
this.configStorage.updateAccessToken(
- accessToken.getAccessToken(), accessToken.getExpiresIn());
- } catch (ClientProtocolException e) {
- throw new RuntimeException(e);
+ accessToken.getAccessToken(), accessToken.getExpiresIn());
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -149,7 +146,7 @@ public class WxCpServiceImpl implements WxCpService {
String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
this.configStorage.updateJsapiTicket(jsapiTicket,
- expiresInSeconds);
+ expiresInSeconds);
}
}
}
@@ -162,10 +159,10 @@ public class WxCpServiceImpl implements WxCpService {
String noncestr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false);
String signature = SHA1.genWithAmple(
- "jsapi_ticket=" + jsapiTicket,
- "noncestr=" + noncestr,
- "timestamp=" + timestamp,
- "url=" + url
+ "jsapi_ticket=" + jsapiTicket,
+ "noncestr=" + noncestr,
+ "timestamp=" + timestamp,
+ "url=" + url
);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setTimestamp(timestamp);
@@ -191,9 +188,9 @@ public class WxCpServiceImpl implements WxCpService {
}
@Override
- public void menuCreate(String agentId, WxMenu menu) throws WxErrorException {
+ public void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid="
- + this.configStorage.getAgentId();
+ + this.configStorage.getAgentId();
post(url, menu.toJson());
}
@@ -203,7 +200,7 @@ public class WxCpServiceImpl implements WxCpService {
}
@Override
- public void menuDelete(String agentId) throws WxErrorException {
+ public void menuDelete(Integer agentId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?agentid=" + agentId;
get(url, null);
}
@@ -214,7 +211,7 @@ public class WxCpServiceImpl implements WxCpService {
}
@Override
- public WxMenu menuGet(String agentId) throws WxErrorException {
+ public WxMenu menuGet(Integer agentId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?agentid=" + agentId;
try {
String resultContent = get(url, null);
@@ -230,7 +227,7 @@ public class WxCpServiceImpl implements WxCpService {
@Override
public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream)
- throws WxErrorException, IOException {
+ throws WxErrorException, IOException {
return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
}
@@ -244,9 +241,9 @@ public class WxCpServiceImpl implements WxCpService {
public File mediaDownload(String media_id) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get";
return execute(
- new MediaDownloadRequestExecutor(
-this.configStorage.getTmpDirFile()),
- url, "media_id=" + media_id);
+ new MediaDownloadRequestExecutor(
+ this.configStorage.getTmpDirFile()),
+ url, "media_id=" + media_id);
}
@@ -254,9 +251,9 @@ this.configStorage.getTmpDirFile()),
public Integer departCreate(WxCpDepart depart) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create";
String responseContent = execute(
- new SimplePostRequestExecutor(),
- url,
- depart.toJson());
+ new SimplePostRequestExecutor(),
+ url,
+ depart.toJson());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id"));
}
@@ -283,11 +280,11 @@ this.configStorage.getTmpDirFile()),
*/
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("department"),
- new TypeToken>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("department"),
+ new TypeToken>() {
+ }.getType()
+ );
}
@Override
@@ -313,8 +310,8 @@ this.configStorage.getTmpDirFile()),
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/batchdelete";
JsonObject jsonObject = new JsonObject();
JsonArray jsonArray = new JsonArray();
- for (int i = 0; i < userids.length; i++) {
- jsonArray.add(new JsonPrimitive(userids[i]));
+ for (String userid : userids) {
+ jsonArray.add(new JsonPrimitive(userid));
}
jsonObject.add("useridlist", jsonArray);
post(url, jsonObject.toString());
@@ -343,11 +340,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, params);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("userlist"),
- new TypeToken>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("userlist"),
+ new TypeToken>() {
+ }.getType()
+ );
}
@Override
@@ -366,11 +363,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, params);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("userlist"),
- new TypeToken>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("userlist"),
+ new TypeToken>() {
+ }.getType()
+ );
}
@Override
@@ -404,11 +401,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("taglist"),
- new TypeToken>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("taglist"),
+ new TypeToken>() {
+ }.getType()
+ );
}
@Override
@@ -417,11 +414,11 @@ this.configStorage.getTmpDirFile()),
String responseContent = get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create()
- .fromJson(
- tmpJsonElement.getAsJsonObject().get("userlist"),
- new TypeToken>() {
- }.getType()
- );
+ .fromJson(
+ tmpJsonElement.getAsJsonObject().get("userlist"),
+ new TypeToken>() {
+ }.getType()
+ );
}
@Override
@@ -460,14 +457,14 @@ this.configStorage.getTmpDirFile()),
}
@Override
- public String oauth2buildAuthorizationUrl(String state) {
- return this.oauth2buildAuthorizationUrl(
-this.configStorage.getOauth2redirectUri(),
- state
- );
- }
+ public String oauth2buildAuthorizationUrl(String state) {
+ return this.oauth2buildAuthorizationUrl(
+ this.configStorage.getOauth2redirectUri(),
+ state
+ );
+ }
- @Override
+ @Override
public String oauth2buildAuthorizationUrl(String redirectUri, String state) {
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
url += "appid=" + this.configStorage.getCorpId();
@@ -487,10 +484,10 @@ this.configStorage.getOauth2redirectUri(),
}
@Override
- public String[] oauth2getUserInfo(String agentId, String code) throws WxErrorException {
+ public String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?"
- + "code=" + code
- + "&agentid=" + agentId;
+ + "code=" + code
+ + "&agentid=" + agentId;
String responseText = get(url, null);
JsonElement je = new JsonParser().parse(responseText);
JsonObject jo = je.getAsJsonObject();
@@ -544,14 +541,14 @@ this.configStorage.getOauth2redirectUri(),
return executeInternal(executor, uri, data);
} catch (WxErrorException e) {
WxError error = e.getError();
- /**
+ /*
* -1 系统繁忙, 1000ms后重试
*/
if (error.getErrorCode() == -1) {
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis,
- retryTimes + 1);
+ retryTimes + 1);
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
@@ -566,7 +563,7 @@ this.configStorage.getOauth2redirectUri(),
}
protected synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
- if (uri.indexOf("access_token=") != -1) {
+ if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}
String accessToken = getAccessToken(false);
@@ -576,7 +573,7 @@ this.configStorage.getOauth2redirectUri(),
try {
return executor.execute(getHttpclient(), this.httpProxy,
- uriWithAccessToken, data);
+ uriWithAccessToken, data);
} catch (WxErrorException e) {
WxError error = e.getError();
/*
@@ -593,8 +590,6 @@ this.configStorage.getOauth2redirectUri(),
throw new WxErrorException(error);
}
return null;
- } catch (ClientProtocolException e) {
- throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -608,15 +603,15 @@ this.configStorage.getOauth2redirectUri(),
public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) {
this.configStorage = wxConfigProvider;
ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage
- .getApacheHttpClientBuilder();
+ .getApacheHttpClientBuilder();
if (null == apacheHttpClientBuilder) {
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get();
}
apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost())
- .httpProxyPort(this.configStorage.getHttpProxyPort())
- .httpProxyUsername(this.configStorage.getHttpProxyUsername())
- .httpProxyPassword(this.configStorage.getHttpProxyPassword());
+ .httpProxyPort(this.configStorage.getHttpProxyPort())
+ .httpProxyUsername(this.configStorage.getHttpProxyUsername())
+ .httpProxyPassword(this.configStorage.getHttpProxyPassword());
if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) {
this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort());
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
index e2422e3b..c25c170b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
@@ -1,17 +1,12 @@
package me.chanjar.weixin.cp.bean;
+import me.chanjar.weixin.cp.bean.messagebuilder.*;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import me.chanjar.weixin.cp.bean.messagebuilder.FileBuilder;
-import me.chanjar.weixin.cp.bean.messagebuilder.ImageBuilder;
-import me.chanjar.weixin.cp.bean.messagebuilder.NewsBuilder;
-import me.chanjar.weixin.cp.bean.messagebuilder.TextBuilder;
-import me.chanjar.weixin.cp.bean.messagebuilder.VideoBuilder;
-import me.chanjar.weixin.cp.bean.messagebuilder.VoiceBuilder;
-import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
-
/**
* 消息
*
@@ -23,7 +18,7 @@ public class WxCpMessage implements Serializable {
private String toUser;
private String toParty;
private String toTag;
- private String agentId;
+ private Integer agentId;
private String msgType;
private String content;
private String mediaId;
@@ -101,11 +96,11 @@ public class WxCpMessage implements Serializable {
this.toTag = toTag;
}
- public String getAgentId() {
+ public Integer getAgentId() {
return this.agentId;
}
- public void setAgentId(String agentId) {
+ public void setAgentId(Integer agentId) {
this.agentId = agentId;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
index 035777d8..7800f1c6 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
@@ -5,13 +5,13 @@ import me.chanjar.weixin.cp.bean.WxCpMessage;
public class BaseBuilder {
protected String msgType;
- protected String agentId;
+ protected Integer agentId;
protected String toUser;
protected String toParty;
protected String toTag;
protected String safe;
- public T agentId(String agentId) {
+ public T agentId(Integer agentId) {
this.agentId = agentId;
return (T) this;
}
diff --git a/weixin-java-mp/build.gradle b/weixin-java-mp/build.gradle
index dcc01548..de1534a3 100644
--- a/weixin-java-mp/build.gradle
+++ b/weixin-java-mp/build.gradle
@@ -6,8 +6,8 @@ dependencies {
testCompile group: 'org.testng', name: 'testng', version:'6.8.7'
testCompile group: 'org.mockito', name: 'mockito-all', version:'1.9.5'
testCompile group: 'com.google.inject', name: 'guice', version:'3.0'
- testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version:'9.3.0.M0'
- testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version:'9.3.0.M0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version:'9.3.0.RC0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version:'9.3.0.RC0'
testCompile group: 'joda-time', name: 'joda-time', version:'2.9.4'
}
test.useTestNG()
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index c1b6a136..ba79d0ca 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
weixin-java-parent
- 2.3.0
+ 2.4.0
weixin-java-mp
WeiXin Java Tools - MP
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
index 3a2e7654..78b1a587 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
@@ -5,6 +5,7 @@ import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
import javax.net.ssl.SSLContext;
import java.io.File;
+import java.util.concurrent.locks.Lock;
/**
* 微信客户端配置存储
@@ -15,6 +16,8 @@ public interface WxMpConfigStorage {
String getAccessToken();
+ Lock getAccessTokenLock();
+
boolean isAccessTokenExpired();
/**
@@ -24,19 +27,21 @@ public interface WxMpConfigStorage {
/**
* 应该是线程安全的
- * @param accessToken
+ * @param accessToken 要更新的WxAccessToken对象
*/
void updateAccessToken(WxAccessToken accessToken);
/**
* 应该是线程安全的
- * @param accessToken
- * @param expiresIn
+ * @param accessToken 新的accessToken值
+ * @param expiresInSeconds 过期时间,以秒为单位
*/
- void updateAccessToken(String accessToken, int expiresIn);
+ void updateAccessToken(String accessToken, int expiresInSeconds);
String getJsapiTicket();
+ Lock getJsapiTicketLock();
+
boolean isJsapiTicketExpired();
/**
@@ -46,12 +51,15 @@ public interface WxMpConfigStorage {
/**
* 应该是线程安全的
- * @param jsapiTicket
+ * @param jsapiTicket 新的jsapi ticket值
+ * @param expiresInSeconds 过期时间,以秒为单位
*/
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
String getCardApiTicket();
+ Lock getCardApiTicketLock();
+
boolean isCardApiTicketExpired();
/**
@@ -61,7 +69,8 @@ public interface WxMpConfigStorage {
/**
* 应该是线程安全的
- * @param cardApiTicket
+ * @param cardApiTicket 新的cardApi ticket值
+ * @param expiresInSeconds 过期时间,以秒为单位
*/
void updateCardApiTicket(String cardApiTicket, int expiresInSeconds);
@@ -70,7 +79,7 @@ public interface WxMpConfigStorage {
String getSecret();
String getPartnerId();
-
+
String getPartnerKey();
String getToken();
@@ -88,7 +97,7 @@ public interface WxMpConfigStorage {
String getHttpProxyUsername();
String getHttpProxyPassword();
-
+
File getTmpDirFile();
SSLContext getSSLContext();
@@ -98,4 +107,9 @@ public interface WxMpConfigStorage {
* @return ApacheHttpClientBuilder
*/
ApacheHttpClientBuilder getApacheHttpClientBuilder();
+
+ /**
+ * 是否自动刷新token
+ */
+ boolean autoRefreshToken();
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
index e75b78da..e874e793 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
@@ -6,6 +6,8 @@ import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
import javax.net.ssl.SSLContext;
import java.io.File;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
/**
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
@@ -36,6 +38,10 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
protected volatile String cardApiTicket;
protected volatile long cardApiTicketExpiresTime;
+ protected Lock accessTokenLock = new ReentrantLock();
+ protected Lock jsapiTicketLock = new ReentrantLock();
+ protected Lock cardApiTicketLock = new ReentrantLock();
+
/**
* 临时文件目录
*/
@@ -50,6 +56,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
return this.accessToken;
}
+ @Override
+ public Lock getAccessTokenLock() {
+ return this.accessTokenLock;
+ }
+
@Override
public boolean isAccessTokenExpired() {
return System.currentTimeMillis() > this.expiresTime;
@@ -63,7 +74,7 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
@Override
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
this.accessToken = accessToken;
- this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
+ this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
}
@Override
@@ -76,6 +87,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
return this.jsapiTicket;
}
+ @Override
+ public Lock getJsapiTicketLock() {
+ return this.jsapiTicketLock;
+ }
+
public void setJsapiTicket(String jsapiTicket) {
this.jsapiTicket = jsapiTicket;
}
@@ -97,7 +113,7 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
this.jsapiTicket = jsapiTicket;
// 预留200秒的时间
- this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
+ this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
}
@Override
@@ -113,6 +129,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
return this.cardApiTicket;
}
+ @Override
+ public Lock getCardApiTicketLock() {
+ return this.cardApiTicketLock;
+ }
+
@Override
public boolean isCardApiTicketExpired() {
return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
@@ -122,7 +143,7 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
this.cardApiTicket = cardApiTicket;
// 预留200秒的时间
- this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
+ this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
}
@Override
@@ -270,6 +291,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
return this.apacheHttpClientBuilder;
}
+ @Override
+ public boolean autoRefreshToken() {
+ return true;
+ }
+
public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
this.apacheHttpClientBuilder = apacheHttpClientBuilder;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java
index 22217801..94359025 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java
@@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult;
/**
* 菜单相关操作接口
@@ -56,4 +57,20 @@ public interface WxMpMenuService {
*/
WxMenu menuTryMatch(String userid) throws WxErrorException;
+ /**
+ *
+ * 获取自定义菜单配置接口
+ * 本接口将会提供公众号当前使用的自定义菜单的配置,如果公众号是通过API调用设置的菜单,则返回菜单的开发配置,而如果公众号是在公众平台官网通过网站功能发布菜单,则本接口返回运营者设置的菜单配置。
+ 请注意:
+ 1、第三方平台开发者可以通过本接口,在旗下公众号将业务授权给你后,立即通过本接口检测公众号的自定义菜单配置,并通过接口再次给公众号设置好自动回复规则,以提升公众号运营者的业务体验。
+ 2、本接口与自定义菜单查询接口的不同之处在于,本接口无论公众号的接口是如何设置的,都能查询到接口,而自定义菜单查询接口则仅能查询到使用API设置的菜单配置。
+ 3、认证/未认证的服务号/订阅号,以及接口测试号,均拥有该接口权限。
+ 4、从第三方平台的公众号登录授权机制上来说,该接口从属于消息与菜单权限集。
+ 5、本接口中返回的图片/语音/视频为临时素材(临时素材每次获取都不同,3天内有效,通过素材管理-获取临时素材接口来获取这些素材),本接口返回的图文消息为永久素材素材(通过素材管理-获取永久素材接口来获取这些素材)。
+ * 接口调用请求说明:
+ http请求方式: GET(请使用https协议)
+ https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=ACCESS_TOKEN
+ *
+ */
+ WxMpGetSelfMenuInfoResult getSelfMenuInfo() throws WxErrorException;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java
index 2fcd4cb9..e1396afb 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpPayService.java
@@ -2,7 +2,6 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback;
-import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderCloseResult;
import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest;
import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest;
import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest;
@@ -13,8 +12,9 @@ import java.io.File;
import java.util.Map;
/**
- * 微信支付相关接口
- * Created by Binary Wang on 2016/7/28.
+ * 微信支付相关接口
+ * Created by Binary Wang on 2016/7/28.
+ *
* @author binarywang (https://github.com/binarywang)
*/
public interface WxMpPayService {
@@ -24,14 +24,15 @@ public interface WxMpPayService {
* 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
* 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
* 需要调用查询接口的情况:
- ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
- ◆ 调用支付接口后,返回系统错误或未知交易状态情况;
- ◆ 调用被扫支付API,返回USERPAYING的状态;
- ◆ 调用关单或撤销接口API之前,需确认支付状态;
+ * ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
+ * ◆ 调用支付接口后,返回系统错误或未知交易状态情况;
+ * ◆ 调用被扫支付API,返回USERPAYING的状态;
+ * ◆ 调用关单或撤销接口API之前,需确认支付状态;
* 接口地址:https://api.mch.weixin.qq.com/pay/orderquery
*
+ *
* @param transactionId 微信支付分配的商户号
- * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。
+ * @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。
* @throws WxErrorException
*/
WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException;
@@ -47,6 +48,7 @@ public interface WxMpPayService {
* 接口地址:https://api.mch.weixin.qq.com/pay/closeorder
* 是否需要证书: 不需要。
*
+ *
* @param outTradeNo 商户系统内部的订单号,当没提供transaction_id时需要传这个。
* @throws WxErrorException
*/
@@ -56,16 +58,18 @@ public interface WxMpPayService {
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
* 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder
- * @throws WxErrorException
- * @param request 请求对象
*
+ * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)
+ * @throws WxErrorException
*/
WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxErrorException;
/**
* 该接口调用“统一下单”接口,并拼装发起支付请求需要的参数
* 详见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
- * @param request 请求对象
+ *
+ * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)
+ * @throws WxErrorException
*/
Map getPayInfo(WxPayUnifiedOrderRequest request) throws WxErrorException;
@@ -75,16 +79,33 @@ public interface WxMpPayService {
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
* 接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
*
+ *
* @param request 请求对象
- * @param keyFile 证书文件对象
+ * @param keyFile 证书文件对象
* @return 退款操作结果
*/
WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) throws WxErrorException;
+ /**
+ *
+ * 微信支付-查询退款
+ * 应用场景:
+ * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
+ * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
+ * 接口链接:https://api.mch.weixin.qq.com/pay/refundquery
+ *
+ * 以下四个参数四选一
+ * @param transactionId 微信订单号
+ * @param outTradeNo 商户订单号
+ * @param outRefundNo 商户退款单号
+ * @param refundId 微信退款单号
+ * @return 退款信息
+ */
+ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId) throws WxErrorException;
+
/**
* 读取支付结果通知
* 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
- *
*/
WxPayJsSDKCallback getJSSDKCallbackData(String xmlData) throws WxErrorException;
@@ -93,7 +114,6 @@ public interface WxMpPayService {
* 计算Map键值对是否和签名相符,
* 按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的 格式(即 key1=value1&key2=value2...)拼接成字符串
*
- *
*/
boolean checkJSSDKCallbackDataSignature(Map kvm, String signature);
@@ -102,13 +122,29 @@ public interface WxMpPayService {
*
* 文档详见:
* 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
+ * 接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
* 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
+ * 接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack
*
+ *
* @param request 请求对象
- * @param keyFile 证书文件对象
+ * @param keyFile 证书文件对象
*/
WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) throws WxErrorException;
+ /**
+ *
+ * 查询红包记录
+ * 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
+ * 请求Url https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
+ * 是否需要证书 是(证书及使用说明详见商户证书)
+ * 请求方式 POST
+ *
+ * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890
+ * @param keyFile 证书文件对象
+ */
+ WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException;
+
/**
*
* 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。
@@ -118,8 +154,9 @@ public interface WxMpPayService {
* 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
* 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
*
+ *
* @param request 请求对象
- * @param keyFile 证书文件对象
+ * @param keyFile 证书文件对象
*/
WxEntPayResult entPay(WxEntPayRequest request, File keyFile) throws WxErrorException;
@@ -130,8 +167,9 @@ public interface WxMpPayService {
* 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
* 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo
*
+ *
* @param partnerTradeNo 商户订单号
- * @param keyFile 证书文件对象
+ * @param keyFile 证书文件对象
*/
WxEntPayQueryResult queryEntPay(String partnerTradeNo, File keyFile) throws WxErrorException;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
index a74e718d..4fa91bad 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
@@ -14,8 +14,8 @@ public interface WxMpService {
/**
*
- * 验证推送过来的消息的正确性
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=验证消息真实性
+ * 验证消息的确来自微信服务器
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319&token=&lang=zh_CN
*
*/
boolean checkSignature(String timestamp, String nonce, String signature);
@@ -36,7 +36,7 @@ public interface WxMpService {
*
* 程序员在非必要情况下尽量不要主动调用此方法
*
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=获取access_token
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183&token=&lang=zh_CN
*
*
* @param forceRefresh 强制刷新
@@ -55,7 +55,7 @@ public interface WxMpService {
* 获得jsapi_ticket
* 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
*
- * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95
+ * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
*
*
* @param forceRefresh 强制刷新
@@ -66,7 +66,7 @@ public interface WxMpService {
*
* 创建调用jsapi时所需要的签名
*
- * 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95
+ * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
*
*/
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
@@ -75,7 +75,7 @@ public interface WxMpService {
*
* 上传群发用的图文消息,上传后才能群发图文消息
*
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
*
*
* @see #massGroupMessageSend(me.chanjar.weixin.mp.bean.WxMpMassTagMessage)
@@ -86,7 +86,7 @@ public interface WxMpService {
/**
*
* 上传群发用的视频,上传后才能群发视频消息
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
*
*
* @see #massGroupMessageSend(me.chanjar.weixin.mp.bean.WxMpMassTagMessage)
@@ -99,7 +99,7 @@ public interface WxMpService {
* 分组群发消息
* 如果发送图文消息,必须先使用 {@link #massNewsUpload(me.chanjar.weixin.mp.bean.WxMpMassNews)} 获得media_id,然后再发送
* 如果发送视频消息,必须先使用 {@link #massVideoUpload(me.chanjar.weixin.mp.bean.WxMpMassVideo)} 获得media_id,然后再发送
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
*
*/
WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException;
@@ -109,7 +109,7 @@ public interface WxMpService {
* 按openId列表群发消息
* 如果发送图文消息,必须先使用 {@link #massNewsUpload(me.chanjar.weixin.mp.bean.WxMpMassNews)} 获得media_id,然后再发送
* 如果发送视频消息,必须先使用 {@link #massVideoUpload(me.chanjar.weixin.mp.bean.WxMpMassVideo)} 获得media_id,然后再发送
- * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
+ * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
*
*/
WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException;
@@ -263,84 +263,84 @@ public interface WxMpService {
WxMpConfigStorage getWxMpConfigStorage();
/**
- * 返回客服接口方法实现类,以方便调用个其各种接口
+ * 返回客服接口方法实现类,以方便调用其各个接口
*
* @return WxMpKefuService
*/
WxMpKefuService getKefuService();
/**
- * 返回素材相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回素材相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpMaterialService
*/
WxMpMaterialService getMaterialService();
/**
- * 返回菜单相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回菜单相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpMenuService
*/
WxMpMenuService getMenuService();
/**
- * 返回用户相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回用户相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpUserService
*/
WxMpUserService getUserService();
/**
- * 返回用户标签相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回用户标签相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpUserTagService
*/
WxMpUserTagService getUserTagService();
/**
- * 返回二维码相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回二维码相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpQrcodeService
*/
WxMpQrcodeService getQrcodeService();
/**
- * 返回卡券相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回卡券相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpCardService
*/
WxMpCardService getCardService();
/**
- * 返回微信支付相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回微信支付相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpPayService
*/
WxMpPayService getPayService();
/**
- * 返回数据分析统计相关接口方法的实现类对象,以方便调用个其各种接口
+ * 返回数据分析统计相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpDataCubeService
*/
WxMpDataCubeService getDataCubeService();
/**
- * 返回用户黑名单管理相关接口方法的实现类对象,以方便调用其各种接口
+ * 返回用户黑名单管理相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpUserBlacklistService
*/
WxMpUserBlacklistService getBlackListService();
/**
- * 返回门店管理相关接口方法的实现类对象,以方便调用其各种接口
+ * 返回门店管理相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpStoreService
*/
WxMpStoreService getStoreService();
/**
- * 返回模板消息相关接口方法的实现类对象,以方便调用其各种接口
+ * 返回模板消息相关接口方法的实现类对象,以方便调用其各个接口
*
* @return WxMpTemplateMsgService
*/
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
index 63e13809..2e6bf88e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
@@ -1,6 +1,7 @@
package me.chanjar.weixin.mp.api.impl;
import java.util.Arrays;
+import java.util.concurrent.locks.Lock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,11 +30,6 @@ public class WxMpCardServiceImpl implements WxMpCardService {
private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class);
- /**
- * 全局的是否正在刷新卡券api_ticket的锁
- */
- private final Object globalCardApiTicketRefreshLock = new Object();
-
private WxMpService wxMpService;
public WxMpCardServiceImpl(WxMpService wxMpService) {
@@ -66,21 +62,25 @@ public class WxMpCardServiceImpl implements WxMpCardService {
*/
@Override
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException {
- if (forceRefresh) {
- this.wxMpService.getWxMpConfigStorage().expireCardApiTicket();
- }
- if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
- synchronized (this.globalCardApiTicketRefreshLock) {
- if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
- String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
- String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
- JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
- JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
- String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
- int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
- this.wxMpService.getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds);
- }
+ Lock lock = wxMpService.getWxMpConfigStorage().getCardApiTicketLock();
+ try {
+ lock.lock();
+
+ if (forceRefresh) {
+ this.wxMpService.getWxMpConfigStorage().expireCardApiTicket();
+ }
+
+ if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
+ String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
+ JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
+ JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
+ String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
+ int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
+ this.wxMpService.getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds);
}
+ } finally {
+ lock.unlock();
}
return this.wxMpService.getWxMpConfigStorage().getCardApiTicket();
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java
index 2f40f709..1373c83d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java
@@ -1,12 +1,13 @@
package me.chanjar.weixin.mp.api.impl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMenuService;
import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult;
+import me.chanjar.weixin.mp.bean.menu.WxMpSelfMenuInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Created by Binary Wang on 2016/7/21.
@@ -14,7 +15,7 @@ import me.chanjar.weixin.mp.api.WxMpService;
public class WxMpMenuServiceImpl implements WxMpMenuService {
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/menu";
private static Logger log = LoggerFactory
- .getLogger(WxMpMenuServiceImpl.class);
+ .getLogger(WxMpMenuServiceImpl.class);
private WxMpService wxMpService;
@@ -74,10 +75,17 @@ public class WxMpMenuServiceImpl implements WxMpMenuService {
} catch (WxErrorException e) {
// 46003 不存在的菜单数据 46002 不存在的菜单版本
if (e.getError().getErrorCode() == 46003
- || e.getError().getErrorCode() == 46002) {
+ || e.getError().getErrorCode() == 46002) {
return null;
}
throw e;
}
}
+
+ @Override
+ public WxMpGetSelfMenuInfoResult getSelfMenuInfo() throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info";
+ String resultContent = this.wxMpService.get(url, null);
+ return WxMpGetSelfMenuInfoResult.fromJson(resultContent);
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
index 3273cd2b..78e76e0f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImpl.java
@@ -8,7 +8,6 @@ import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.WxMpPayService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.pay.WxPayJsSDKCallback;
-import me.chanjar.weixin.mp.bean.pay.result.WxPayOrderCloseResult;
import me.chanjar.weixin.mp.bean.pay.request.*;
import me.chanjar.weixin.mp.bean.pay.result.*;
import org.apache.commons.codec.digest.DigestUtils;
@@ -42,13 +41,11 @@ import java.util.*;
*/
public class WxMpPayServiceImpl implements WxMpPayService {
- protected final Logger log = LoggerFactory.getLogger(this.getClass());
-
private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com";
- private static final String[] TRADE_TYPES = new String[]{"JSAPI","NATIVE", "APP"};
- private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS",
+ private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP"};
+ private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS",
"REFUND_SOURCE_UNSETTLED_FUNDS"};
-
+ protected final Logger log = LoggerFactory.getLogger(this.getClass());
private WxMpService wxMpService;
public WxMpPayServiceImpl(WxMpService wxMpService) {
@@ -57,7 +54,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
@Override
public WxPayRefundResult refund(WxPayRefundRequest request, File keyFile)
- throws WxErrorException {
+ throws WxErrorException {
checkParameters(request);
XStream xstream = XStreamInitializer.getInstance();
@@ -67,7 +64,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
String partnerId = this.wxMpService.getWxMpConfigStorage().getPartnerId();
request.setMchId(partnerId);
- request.setNonceStr( System.currentTimeMillis() + "");
+ request.setNonceStr(System.currentTimeMillis() + "");
request.setOpUserId(partnerId);
String sign = this.createSign(BeanUtils.xmlBean2Map(request), this.wxMpService.getWxMpConfigStorage().getPartnerKey());
request.setSign(sign);
@@ -79,11 +76,45 @@ public class WxMpPayServiceImpl implements WxMpPayService {
return result;
}
+ @Override
+ public WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId) throws WxErrorException {
+ if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo) && StringUtils.isBlank(outRefundNo) && StringUtils.isBlank(refundId)) ||
+ (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(outTradeNo) && StringUtils.isNotBlank(outRefundNo) && StringUtils.isNotBlank(refundId))) {
+ throw new IllegalArgumentException("transaction_id , out_trade_no,out_refund_no, refund_id 必须四选一");
+ }
+
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.processAnnotations(WxPayRefundQueryRequest.class);
+ xstream.processAnnotations(WxPayRefundQueryResult.class);
+
+ WxPayRefundQueryRequest request = new WxPayRefundQueryRequest();
+ request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
+ request.setTransactionId(StringUtils.trimToNull(transactionId));
+ request.setOutRefundNo(StringUtils.trimToNull(outRefundNo));
+ request.setRefundId(StringUtils.trimToNull(refundId));
+
+ request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
+ request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId());
+ request.setNonceStr(System.currentTimeMillis() + "");
+
+ String sign = this.createSign(BeanUtils.xmlBean2Map(request),
+ this.wxMpService.getWxMpConfigStorage().getPartnerKey());
+ request.setSign(sign);
+
+ String url = PAY_BASE_URL + "/pay/refundquery";
+
+ String responseContent = this.executeRequest(url, xstream.toXML(request));
+ WxPayRefundQueryResult result = (WxPayRefundQueryResult) xstream.fromXML(responseContent);
+ result.composeRefundRecords(responseContent);
+ this.checkResult(result);
+ return result;
+ }
+
private void checkResult(WxPayBaseResult result) throws WxErrorException {
if (!"SUCCESS".equalsIgnoreCase(result.getReturnCode())
|| !"SUCCESS".equalsIgnoreCase(result.getResultCode())) {
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1)
- .setErrorMsg("返回代码:" + result.getReturnCode() + ", 返回信息: "
+ .setErrorMsg("返回代码: " + result.getReturnCode() + ", 返回信息: "
+ result.getReturnMsg() + ", 结果代码: " + result.getResultCode() + ", 错误代码: "
+ result.getErrCode() + ", 错误详情: " + result.getErrCodeDes())
.build());
@@ -94,7 +125,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
BeanUtils.checkRequiredFields(request);
if (StringUtils.isNotBlank(request.getRefundAccount())) {
- if(!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())){
+ if (!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())) {
throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一");
}
}
@@ -118,14 +149,14 @@ public class WxMpPayServiceImpl implements WxMpPayService {
@Override
public boolean checkJSSDKCallbackDataSignature(Map kvm,
- String signature) {
+ String signature) {
return signature.equals(this.createSign(kvm,
- this.wxMpService.getWxMpConfigStorage().getPartnerKey()));
+ this.wxMpService.getWxMpConfigStorage().getPartnerKey()));
}
@Override
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile)
- throws WxErrorException {
+ throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPaySendRedpackRequest.class);
xstream.processAnnotations(WxPaySendRedpackResult.class);
@@ -136,7 +167,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setNonceStr(System.currentTimeMillis() + "");
String sign = this.createSign(BeanUtils.xmlBean2Map(request),
- this.wxMpService.getWxMpConfigStorage().getPartnerKey());
+ this.wxMpService.getWxMpConfigStorage().getPartnerKey());
request.setSign(sign);
String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack";
@@ -147,25 +178,52 @@ public class WxMpPayServiceImpl implements WxMpPayService {
String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId);
WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream
- .fromXML(responseContent);
+ .fromXML(responseContent);
+ this.checkResult(result);
+ return result;
+ }
+
+ @Override
+ public WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException {
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.processAnnotations(WxPayRedpackQueryRequest.class);
+ xstream.processAnnotations(WxPayRedpackQueryResult.class);
+
+ WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest();
+ request.setMchBillNo(mchBillNo);
+ request.setBillType("MCHT");
+
+ request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
+ String mchId = this.wxMpService.getWxMpConfigStorage().getPartnerId();
+ request.setMchId(mchId);
+ request.setNonceStr(System.currentTimeMillis() + "");
+
+ String sign = this.createSign(BeanUtils.xmlBean2Map(request),
+ this.wxMpService.getWxMpConfigStorage().getPartnerKey());
+ request.setSign(sign);
+
+ String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo";
+ String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), mchId);
+ WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent);
this.checkResult(result);
return result;
}
/**
* 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3)
+ *
* @param packageParams 原始参数
- * @param signKey 加密Key(即 商户Key)
+ * @param signKey 加密Key(即 商户Key)
* @return 签名字符串
*/
private String createSign(Map packageParams, String signKey) {
SortedMap sortedMap = new TreeMap<>(packageParams);
- StringBuffer toSign = new StringBuffer();
+ StringBuilder toSign = new StringBuilder();
for (String key : sortedMap.keySet()) {
String value = packageParams.get(key);
if (null != value && !"".equals(value) && !"sign".equals(key)
- && !"key".equals(key)) {
+ && !"key".equals(key)) {
toSign.append(key + "=" + value + "&");
}
}
@@ -237,7 +295,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
@Override
public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request)
- throws WxErrorException {
+ throws WxErrorException {
checkParameters(request);
XStream xstream = XStreamInitializer.getInstance();
@@ -249,14 +307,14 @@ public class WxMpPayServiceImpl implements WxMpPayService {
request.setNonceStr(System.currentTimeMillis() + "");
String sign = this.createSign(BeanUtils.xmlBean2Map(request),
- this.wxMpService.getWxMpConfigStorage().getPartnerKey());
+ this.wxMpService.getWxMpConfigStorage().getPartnerKey());
request.setSign(sign);
String url = PAY_BASE_URL + "/pay/unifiedorder";
String responseContent = this.executeRequest(url, xstream.toXML(request));
WxPayUnifiedOrderResult result = (WxPayUnifiedOrderResult) xstream
- .fromXML(responseContent);
+ .fromXML(responseContent);
this.checkResult(result);
return result;
}
@@ -264,7 +322,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
private void checkParameters(WxPayUnifiedOrderRequest request) throws WxErrorException {
BeanUtils.checkRequiredFields(request);
- if (! ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) {
+ if (!ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) {
throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一");
}
@@ -283,7 +341,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
String prepayId = unifiedOrderResult.getPrepayId();
if (StringUtils.isBlank(prepayId)) {
throw new RuntimeException(String.format("Failed to get prepay id due to error code '%s'(%s).",
- unifiedOrderResult.getErrCode(), unifiedOrderResult.getErrCodeDes()));
+ unifiedOrderResult.getErrCode(), unifiedOrderResult.getErrCodeDes()));
}
Map payInfo = new HashMap<>();
@@ -347,7 +405,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
return result;
}
- private String executeRequest( String url, String requestStr) throws WxErrorException {
+ private String executeRequest(String url, String requestStr) throws WxErrorException {
HttpPost httpPost = new HttpPost(url);
if (this.wxMpService.getHttpProxy() != null) {
httpPost.setConfig(RequestConfig.custom().setProxy(this.wxMpService.getHttpProxy()).build());
@@ -358,25 +416,25 @@ public class WxMpPayServiceImpl implements WxMpPayService {
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String result = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
- this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",url, requestStr, result);
+ this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", url, requestStr, result);
return result;
}
} catch (IOException e) {
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", url, requestStr, e.getMessage());
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e);
- }finally {
+ } finally {
httpPost.releaseConnection();
}
}
- private String executeRequestWithKeyFile( String url, File keyFile, String requestStr, String mchId) throws WxErrorException {
+ private String executeRequestWithKeyFile(String url, File keyFile, String requestStr, String mchId) throws WxErrorException {
try (FileInputStream inputStream = new FileInputStream(keyFile)) {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(inputStream, mchId.toCharArray());
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
- SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
- new DefaultHostnameVerifier());
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,
+ new DefaultHostnameVerifier());
HttpPost httpPost = new HttpPost(url);
if (this.wxMpService.getHttpProxy() != null) {
@@ -387,10 +445,10 @@ public class WxMpPayServiceImpl implements WxMpPayService {
httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1")));
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String result = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
- this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",url, requestStr, result);
+ this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", url, requestStr, result);
return result;
}
- }finally {
+ } finally {
httpPost.releaseConnection();
}
} catch (Exception e) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
index 87cf7397..46fa3157 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.util.concurrent.locks.Lock;
public class WxMpServiceImpl implements WxMpService {
@@ -35,16 +36,6 @@ public class WxMpServiceImpl implements WxMpService {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
- /**
- * 全局的是否正在刷新access token的锁
- */
- private final Object globalAccessTokenRefreshLock = new Object();
-
- /**
- * 全局的是否正在刷新jsapi_ticket的锁
- */
- private final Object globalJsapiTicketRefreshLock = new Object();
-
private WxMpConfigStorage configStorage;
private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this);
@@ -98,38 +89,42 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
- if (forceRefresh) {
- this.configStorage.expireAccessToken();
- }
- if (this.configStorage.isAccessTokenExpired()) {
- synchronized (this.globalAccessTokenRefreshLock) {
- if (this.configStorage.isAccessTokenExpired()) {
- String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
- "&appid=" + this.configStorage.getAppId() + "&secret="
- + this.configStorage.getSecret();
- try {
- HttpGet httpGet = new HttpGet(url);
- if (this.httpProxy != null) {
- RequestConfig config = RequestConfig.custom().setProxy(this.httpProxy).build();
- httpGet.setConfig(config);
- }
- try (CloseableHttpResponse response = getHttpclient().execute(httpGet)) {
- String resultContent = new BasicResponseHandler().handleResponse(response);
- WxError error = WxError.fromJson(resultContent);
- if (error.getErrorCode() != 0) {
- throw new WxErrorException(error);
- }
- WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
- this.configStorage.updateAccessToken(accessToken.getAccessToken(),
- accessToken.getExpiresIn());
- }finally {
- httpGet.releaseConnection();
+ Lock lock = this.configStorage.getAccessTokenLock();
+ try {
+ lock.lock();
+
+ if (forceRefresh) {
+ this.configStorage.expireAccessToken();
+ }
+
+ if (this.configStorage.isAccessTokenExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
+ "&appid=" + this.configStorage.getAppId() + "&secret="
+ + this.configStorage.getSecret();
+ try {
+ HttpGet httpGet = new HttpGet(url);
+ if (this.httpProxy != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(this.httpProxy).build();
+ httpGet.setConfig(config);
+ }
+ try (CloseableHttpResponse response = getHttpclient().execute(httpGet)) {
+ String resultContent = new BasicResponseHandler().handleResponse(response);
+ WxError error = WxError.fromJson(resultContent);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
}
- } catch (IOException e) {
- throw new RuntimeException(e);
+ WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+ this.configStorage.updateAccessToken(accessToken.getAccessToken(),
+ accessToken.getExpiresIn());
+ }finally {
+ httpGet.releaseConnection();
}
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
+ } finally {
+ lock.unlock();
}
return this.configStorage.getAccessToken();
}
@@ -141,22 +136,25 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
- if (forceRefresh) {
- this.configStorage.expireJsapiTicket();
- }
+ Lock lock = this.configStorage.getJsapiTicketLock();
+ try {
+ lock.lock();
- if (this.configStorage.isJsapiTicketExpired()) {
- synchronized (this.globalJsapiTicketRefreshLock) {
- if (this.configStorage.isJsapiTicketExpired()) {
- String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
- String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
- JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
- JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
- String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
- int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
- this.configStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds);
- }
+ if (forceRefresh) {
+ this.configStorage.expireJsapiTicket();
+ }
+
+ if (this.configStorage.isJsapiTicketExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
+ String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
+ JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
+ JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
+ String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
+ int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
+ this.configStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds);
}
+ } finally {
+ lock.unlock();
}
return this.configStorage.getJsapiTicket();
}
@@ -370,9 +368,7 @@ public class WxMpServiceImpl implements WxMpService {
return result;
} catch (WxErrorException e) {
WxError error = e.getError();
- /**
- * -1 系统繁忙, 1000ms后重试
- */
+ // -1 系统繁忙, 1000ms后重试
if (error.getErrorCode() == -1) {
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try {
@@ -411,8 +407,11 @@ public class WxMpServiceImpl implements WxMpService {
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) {
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
this.configStorage.expireAccessToken();
- return this.execute(executor, uri, data);
+ if(this.configStorage.autoRefreshToken()){
+ return this.execute(executor, uri, data);
+ }
}
+
if (error.getErrorCode() != 0) {
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data,
error);
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java
index 38bd8ea7..982cb78f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java
@@ -1,13 +1,13 @@
package me.chanjar.weixin.mp.bean;
-import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
/**
- * OpenId列表群发的消息
+ * openid列表群发的消息
*
* @author chanjarster
*/
@@ -64,17 +64,26 @@ public class WxMpMassOpenIdsMessage implements Serializable {
}
/**
- * OpenId列表,最多支持10,000个
+ * openid列表,最多支持10,000个
*/
public List getToUsers() {
return this.toUsers;
}
/**
- * 添加OpenId,最多支持10,000个
- * @param openId
+ * 添加openid,最多支持10,000个
+ * @param openid
*/
- public void addUser(String openId) {
- this.toUsers.add(openId);
+ public void addUser(String openid) {
+ this.toUsers.add(openid);
}
+
+ /**
+ * 提供set方法,方便客户端直接设置所有群发对象的openid列表
+ * @param toUsers
+ */
+ public void setToUsers(List toUsers) {
+ this.toUsers = toUsers;
+ }
+
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java
index e228a3cc..251c5e76 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java
@@ -14,7 +14,7 @@ public class WxDataCubeArticleTotalDetail {
* 统计的日期,在getarticletotal接口中,ref_date指的是文章群发出日期, 而stat_date是数据统计日期
*/
@SerializedName("stat_date")
- private Integer statDate;
+ private String statDate;
/**
* target_user
@@ -191,11 +191,11 @@ public class WxDataCubeArticleTotalDetail {
@SerializedName("feed_share_from_other_cnt")
private Integer feedShareFromOtherCnt;
- public Integer getStatDate() {
+ public String getStatDate() {
return this.statDate;
}
- public void setStatDate(Integer statDate) {
+ public void setStatDate(String statDate) {
this.statDate = statDate;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java
index 70b11fbf..f67a8cb4 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java
@@ -31,7 +31,7 @@ public class WxMpMaterialNews implements Serializable {
/**
*
* 群发图文消息article
- * 1. thumbMediaId (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得
+ * 1. thumbMediaId (必填) 图文消息的封面图片素材id(必须是永久mediaID)
* 2. author 图文消息的作者
* 3. title (必填) 图文消息的标题
* 4. contentSourceUrl 在图文消息页面点击“阅读原文”后的页面链接
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java
new file mode 100644
index 00000000..b78d2dc3
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.mp.bean.menu;
+
+import com.google.gson.annotations.SerializedName;
+import me.chanjar.weixin.common.util.ToStringUtils;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+/**
+ *
+ * Created by Binary Wang on 2016-11-25.
+ * @author binarywang(Binary Wang)
+ *
+ */
+public class WxMpGetSelfMenuInfoResult {
+ @SerializedName("selfmenu_info")
+ private WxMpSelfMenuInfo selfMenuInfo;
+
+ @SerializedName("is_menu_open")
+ private Integer isMenuOpen;
+
+ public static WxMpGetSelfMenuInfoResult fromJson(String json) {
+ return WxGsonBuilder.create().fromJson(json, WxMpGetSelfMenuInfoResult.class);
+ }
+
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ public WxMpSelfMenuInfo getSelfMenuInfo() {
+ return selfMenuInfo;
+ }
+
+ public void setSelfMenuInfo(WxMpSelfMenuInfo selfMenuInfo) {
+ this.selfMenuInfo = selfMenuInfo;
+ }
+
+ public Integer getIsMenuOpen() {
+ return isMenuOpen;
+ }
+
+ public void setIsMenuOpen(Integer isMenuOpen) {
+ this.isMenuOpen = isMenuOpen;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java
new file mode 100644
index 00000000..f2c0c4ca
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java
@@ -0,0 +1,288 @@
+package me.chanjar.weixin.mp.bean.menu;
+
+import com.google.gson.annotations.SerializedName;
+import me.chanjar.weixin.common.util.ToStringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * Created by Binary Wang on 2016-11-25.
+ * @author binarywang(Binary Wang)
+ *
+ */
+public class WxMpSelfMenuInfo {
+ /**
+ * 菜单按钮
+ */
+ @SerializedName("button")
+ private List buttons;
+
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ public static class WxMpSelfMenuButton {
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ /**
+ *
+ * 菜单的类型,公众平台官网上能够设置的菜单类型有view(跳转网页)、text(返回文本,下同)、img、photo、video、voice。
+ * 使用API设置的则有8种,详见《自定义菜单创建接口》
+ *
+ */
+ @SerializedName("type")
+ private String type;
+
+ /**
+ * 菜单名称
+ */
+ @SerializedName("name")
+ private String name;
+
+ /**
+ *
+ * 对于不同的菜单类型,value的值意义不同。
+ * 官网上设置的自定义菜单:
+ *
Text:保存文字到value;
+ * Img、voice:保存mediaID到value;
+ * Video:保存视频下载链接到value;
+ * News:保存图文消息到news_info,同时保存mediaID到value;
+ * View:保存链接到url。
+ *
+ * 使用API设置的自定义菜单:
+ * click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、 pic_weixin、location_select:保存值到key;
+ * view:保存链接到url
+ *
+ */
+ @SerializedName("key")
+ private String key;
+
+ /**
+ * @see #key
+ */
+ @SerializedName("url")
+ private String url;
+
+ /**
+ * @see #key
+ */
+ @SerializedName("value")
+ private String value;
+
+ /**
+ * 子菜单信息
+ */
+ @SerializedName("sub_button")
+ private SubButtons subButtons;
+
+ public SubButtons getSubButtons() {
+ return subButtons;
+ }
+
+ public void setSubButtons(SubButtons subButtons) {
+ this.subButtons = subButtons;
+ }
+
+ public static class SubButtons {
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ @SerializedName("list")
+ private List subButtons = new ArrayList<>();
+
+ public List getSubButtons() {
+ return subButtons;
+ }
+
+ public void setSubButtons(List subButtons) {
+ this.subButtons = subButtons;
+ }
+ }
+
+ /**
+ * 图文消息的信息
+ */
+ @SerializedName("news_info")
+ private NewsInfo newsInfo;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public NewsInfo getNewsInfo() {
+ return newsInfo;
+ }
+
+ public void setNewsInfo(NewsInfo newsInfo) {
+ this.newsInfo = newsInfo;
+ }
+
+ public static class NewsInfo {
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ @SerializedName("list")
+ private List news = new ArrayList<>();
+
+ public List getNews() {
+ return news;
+ }
+
+ public void setNews(List news) {
+ this.news = news;
+ }
+
+ public static class NewsInButton {
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ /**
+ * 图文消息的标题
+ */
+ @SerializedName("title")
+ private String title;
+
+ /**
+ * 摘要
+ */
+ @SerializedName("digest")
+ private String digest;
+
+ /**
+ * 作者
+ */
+ @SerializedName("author")
+ private String author;
+
+ /**
+ * show_cover
+ * 是否显示封面,0为不显示,1为显示
+ */
+ @SerializedName("show_cover")
+ private Integer showCover;
+
+ /**
+ * 封面图片的URL
+ */
+ @SerializedName("cover_url")
+ private String coverUrl;
+
+ /**
+ * 正文的URL
+ */
+ @SerializedName("content_url")
+ private String contentUrl;
+
+ /**
+ * 原文的URL,若置空则无查看原文入口
+ */
+ @SerializedName("source_url")
+ private String sourceUrl;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDigest() {
+ return digest;
+ }
+
+ public void setDigest(String digest) {
+ this.digest = digest;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public Integer getShowCover() {
+ return showCover;
+ }
+
+ public void setShowCover(Integer showCover) {
+ this.showCover = showCover;
+ }
+
+ public String getCoverUrl() {
+ return coverUrl;
+ }
+
+ public void setCoverUrl(String coverUrl) {
+ this.coverUrl = coverUrl;
+ }
+
+ public String getContentUrl() {
+ return contentUrl;
+ }
+
+ public void setContentUrl(String contentUrl) {
+ this.contentUrl = contentUrl;
+ }
+
+ public String getSourceUrl() {
+ return sourceUrl;
+ }
+
+ public void setSourceUrl(String sourceUrl) {
+ this.sourceUrl = sourceUrl;
+ }
+ }
+ }
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
index 732c0d54..36b4c104 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
@@ -263,6 +263,118 @@ public class WxMpXmlMessage implements Serializable {
@XStreamAlias("FailReason")
private String failReason;
+
+ ///////////////////////////////////////
+ // 微信硬件平台相关事件推送
+ ///////////////////////////////////////
+ /**
+ * 设备类型,目前为"公众账号原始ID"
+ */
+ @XStreamAlias("DeviceType")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String deviceType;
+
+ /**
+ * 设备ID,第三方提供
+ */
+ @XStreamAlias("DeviceID")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String deviceId;
+
+
+ @XStreamAlias("HardWare")
+ private HardWare hardWare = new HardWare();
+
+ /**
+ * 请求类型:0:退订设备状态;1:心跳;(心跳的处理方式跟订阅一样)2:订阅设备状态
+ */
+ @XStreamAlias("OpType")
+ private Integer opType;
+
+ /**
+ * 设备状态:0:未连接;1:已连接
+ */
+ @XStreamAlias("DeviceStatus")
+ private Integer deviceStatus;
+
+ public static WxMpXmlMessage fromXml(String xml) {
+ return XStreamTransformer.fromXml(WxMpXmlMessage.class, xml);
+ }
+
+ public static WxMpXmlMessage fromXml(InputStream is) {
+ return XStreamTransformer.fromXml(WxMpXmlMessage.class, is);
+ }
+
+ /**
+ * 从加密字符串转换
+ *
+ * @param encryptedXml
+ * @param wxMpConfigStorage
+ * @param timestamp
+ * @param nonce
+ * @param msgSignature
+ */
+ public static WxMpXmlMessage fromEncryptedXml(String encryptedXml,
+ WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce,
+ String msgSignature) {
+ WxMpCryptUtil cryptUtil = new WxMpCryptUtil(wxMpConfigStorage);
+ String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce,
+ encryptedXml);
+ return fromXml(plainText);
+ }
+
+ public static WxMpXmlMessage fromEncryptedXml(InputStream is,
+ WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce,
+ String msgSignature) {
+ try {
+ return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxMpConfigStorage,
+ timestamp, nonce, msgSignature);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Integer getOpType() {
+ return opType;
+ }
+
+ public void setOpType(Integer opType) {
+ this.opType = opType;
+ }
+
+ public Integer getDeviceStatus() {
+
+ return deviceStatus;
+ }
+
+ public void setDeviceStatus(Integer deviceStatus) {
+ this.deviceStatus = deviceStatus;
+ }
+
+ public HardWare getHardWare() {
+ return hardWare;
+ }
+
+ public void setHardWare(HardWare hardWare) {
+ this.hardWare = hardWare;
+ }
+
+ public String getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+
+ public String getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
public Long getExpiredTime() {
return this.expiredTime;
}
@@ -346,7 +458,6 @@ public class WxMpXmlMessage implements Serializable {
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LINK}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_EVENT}
*
- *
*/
public String getMsgType() {
return this.msgType;
@@ -537,43 +648,6 @@ public class WxMpXmlMessage implements Serializable {
this.fromUser = fromUser;
}
- public static WxMpXmlMessage fromXml(String xml) {
- return XStreamTransformer.fromXml(WxMpXmlMessage.class, xml);
- }
-
- public static WxMpXmlMessage fromXml(InputStream is) {
- return XStreamTransformer.fromXml(WxMpXmlMessage.class, is);
- }
-
- /**
- * 从加密字符串转换
- *
- * @param encryptedXml
- * @param wxMpConfigStorage
- * @param timestamp
- * @param nonce
- * @param msgSignature
- */
- public static WxMpXmlMessage fromEncryptedXml(String encryptedXml,
- WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce,
- String msgSignature) {
- WxMpCryptUtil cryptUtil = new WxMpCryptUtil(wxMpConfigStorage);
- String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce,
- encryptedXml);
- return fromXml(plainText);
- }
-
- public static WxMpXmlMessage fromEncryptedXml(InputStream is,
- WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce,
- String msgSignature) {
- try {
- return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxMpConfigStorage,
- timestamp, nonce, msgSignature);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
public String getStatus() {
return this.status;
}
@@ -683,7 +757,7 @@ public class WxMpXmlMessage implements Serializable {
}
public void setSendLocationInfo(
- WxMpXmlMessage.SendLocationInfo sendLocationInfo) {
+ WxMpXmlMessage.SendLocationInfo sendLocationInfo) {
this.sendLocationInfo = sendLocationInfo;
}
@@ -719,21 +793,62 @@ public class WxMpXmlMessage implements Serializable {
this.fromKfAccount = fromKfAccount;
}
- @XStreamAlias("ScanCodeInfo")
- public static class ScanCodeInfo {
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
+ @XStreamAlias("HardWare")
+ public static class HardWare {
+ /**
+ * 消息展示,目前支持myrank(排行榜)
+ */
+ @XStreamAlias("MessageView")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String messageView;
+ /**
+ * 消息点击动作,目前支持ranklist(点击跳转排行榜)
+ */
+ @XStreamAlias("MessageAction")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String messageAction;
+
@Override
public String toString() {
return ToStringUtils.toSimpleString(this);
}
+ public String getMessageView() {
+ return messageView;
+ }
+
+ public void setMessageView(String messageView) {
+ this.messageView = messageView;
+ }
+
+ public String getMessageAction() {
+ return messageAction;
+ }
+
+ public void setMessageAction(String messageAction) {
+ this.messageAction = messageAction;
+ }
+ }
+
+ @XStreamAlias("ScanCodeInfo")
+ public static class ScanCodeInfo {
@XStreamAlias("ScanType")
@XStreamConverter(value = XStreamCDataConverter.class)
private String scanType;
-
@XStreamAlias("ScanResult")
@XStreamConverter(value = XStreamCDataConverter.class)
private String scanResult;
+ @Override
+ public String toString() {
+ return ToStringUtils.toSimpleString(this);
+ }
+
/**
* 扫描类型,一般是qrcode
*/
@@ -761,17 +876,16 @@ public class WxMpXmlMessage implements Serializable {
@XStreamAlias("SendPicsInfo")
public static class SendPicsInfo {
+ @XStreamAlias("PicList")
+ protected final List- picList = new ArrayList<>();
+ @XStreamAlias("Count")
+ private Long count;
+
@Override
public String toString() {
return ToStringUtils.toSimpleString(this);
}
- @XStreamAlias("Count")
- private Long count;
-
- @XStreamAlias("PicList")
- protected final List
- picList = new ArrayList<>();
-
public Long getCount() {
return this.count;
}
@@ -786,15 +900,15 @@ public class WxMpXmlMessage implements Serializable {
@XStreamAlias("item")
public static class Item {
+ @XStreamAlias("PicMd5Sum")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String picMd5Sum;
+
@Override
public String toString() {
return ToStringUtils.toSimpleString(this);
}
- @XStreamAlias("PicMd5Sum")
- @XStreamConverter(value = XStreamCDataConverter.class)
- private String picMd5Sum;
-
public String getPicMd5Sum() {
return this.picMd5Sum;
}
@@ -873,9 +987,4 @@ public class WxMpXmlMessage implements Serializable {
this.poiname = poiname;
}
}
-
- @Override
- public String toString() {
- return ToStringUtils.toSimpleString(this);
- }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRedpackQueryRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRedpackQueryRequest.java
new file mode 100644
index 00000000..de7eee93
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRedpackQueryRequest.java
@@ -0,0 +1,57 @@
+package me.chanjar.weixin.mp.bean.pay.request;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ *
+ * 注释中各行对应含义:
+ * 字段名
+ * 字段
+ * 必填
+ * 示例值
+ * 类型
+ * 说明
+ * Created by Binary Wang on 2016-11-28.
+ * @author binarywang(Binary Wang)
+ *
+ */
+@XStreamAlias("xml")
+public class WxPayRedpackQueryRequest extends WxPayBaseRequest {
+ /**
+ * 商户订单号
+ * mch_billno
+ * 是
+ * 10000098201411111234567890
+ * String(28)
+ * 商户发放红包的商户订单号
+ */
+ @XStreamAlias("mch_billno")
+ private String mchBillNo;
+
+ /**
+ * 订单类型
+ * bill_type
+ * 是
+ * MCHT
+ * String(32)
+ * MCHT:通过商户订单号获取红包信息。
+ */
+ @XStreamAlias("bill_type")
+ private String billType;
+
+ public String getBillType() {
+ return billType;
+ }
+
+ public void setBillType(String billType) {
+ this.billType = billType;
+ }
+
+ public String getMchBillNo() {
+ return mchBillNo;
+ }
+
+ public void setMchBillNo(String mchBillNo) {
+ this.mchBillNo = mchBillNo;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundQueryRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundQueryRequest.java
new file mode 100644
index 00000000..373b0917
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPayRefundQueryRequest.java
@@ -0,0 +1,135 @@
+package me.chanjar.weixin.mp.bean.pay.request;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ *
+ * Created by Binary Wang on 2016-11-24.
+ * @author binarywang(Binary Wang)
+ *
+ */
+@XStreamAlias("xml")
+public class WxPayRefundQueryRequest extends WxPayBaseRequest {
+ /**
+ *
+ * 设备号
+ * device_info
+ * 否
+ * String(32)
+ * 013467007045764
+ * 商户自定义的终端设备号,如门店编号、设备的ID等
+ *
+ */
+ @XStreamAlias("device_info")
+ private String deviceInfo;
+
+ /**
+ *
+ * 签名类型
+ * sign_type
+ * 否
+ * String(32)
+ * HMAC-SHA256
+ * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
+ *
+ */
+ @XStreamAlias("sign_type")
+ private String signType;
+
+ //************以下四选一************
+ /**
+ *
+ * 微信订单号
+ * transaction_id
+ * String(32)
+ * 1217752501201407033233368018
+ * 微信订单号
+ *
+ */
+ @XStreamAlias("transaction_id")
+ private String transactionId;
+
+ /**
+ *
+ * 商户订单号
+ * out_trade_no
+ * String(32)
+ * 1217752501201407033233368018
+ * 商户系统内部的订单号
+ *
+ */
+ @XStreamAlias("out_trade_no")
+ private String outTradeNo;
+
+ /**
+ *
+ * 商户退款单号
+ * out_refund_no
+ * String(32)
+ * 1217752501201407033233368018
+ * 商户侧传给微信的退款单号
+ *
+ */
+ @XStreamAlias("out_refund_no")
+ private String outRefundNo;
+
+ /**
+ *
+ * 微信退款单号
+ * refund_id
+ * String(28)
+ * 1217752501201407033233368018
+ * 微信生成的退款单号,在申请退款接口有返回
+ *
+ */
+ @XStreamAlias("refund_id")
+ private String refundId;
+
+ public String getDeviceInfo() {
+ return deviceInfo;
+ }
+
+ public void setDeviceInfo(String deviceInfo) {
+ this.deviceInfo = deviceInfo;
+ }
+
+ public String getSignType() {
+ return signType;
+ }
+
+ public void setSignType(String signType) {
+ this.signType = signType;
+ }
+
+ public String getTransactionId() {
+ return transactionId;
+ }
+
+ public void setTransactionId(String transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ public String getOutTradeNo() {
+ return outTradeNo;
+ }
+
+ public void setOutTradeNo(String outTradeNo) {
+ this.outTradeNo = outTradeNo;
+ }
+
+ public String getOutRefundNo() {
+ return outRefundNo;
+ }
+
+ public void setOutRefundNo(String outRefundNo) {
+ this.outRefundNo = outRefundNo;
+ }
+
+ public String getRefundId() {
+ return refundId;
+ }
+
+ public void setRefundId(String refundId) {
+ this.refundId = refundId;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java
index cad2cc52..535b2941 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/request/WxPaySendRedpackRequest.java
@@ -14,7 +14,7 @@ public class WxPaySendRedpackRequest {
* 商户订单号(每个订单号必须唯一) 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。
*/
@XStreamAlias("mch_billno")
- private String mchBillno;
+ private String mchBillNo;
/**
* send_name
@@ -157,12 +157,12 @@ public class WxPaySendRedpackRequest {
@XStreamAlias("consume_mch_id")
private String consumeMchId;
- public String getMchBillno() {
- return this.mchBillno;
+ public String getMchBillNo() {
+ return mchBillNo;
}
- public void setMchBillno(String mchBillno) {
- this.mchBillno = mchBillno;
+ public void setMchBillNo(String mchBillNo) {
+ this.mchBillNo = mchBillNo;
}
public String getSendName() {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java
index 17b3a412..373497f3 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayOrderQueryResult.java
@@ -1,10 +1,10 @@
package me.chanjar.weixin.mp.bean.pay.result;
-import java.util.List;
-
import com.google.common.collect.Lists;
import com.thoughtworks.xstream.annotations.XStreamAlias;
+import java.util.List;
+
/**
*
* 查询订单 返回结果对象
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRedpackQueryResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRedpackQueryResult.java
new file mode 100644
index 00000000..faf2df67
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRedpackQueryResult.java
@@ -0,0 +1,405 @@
+package me.chanjar.weixin.mp.bean.pay.result;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ *
+ * 注释中各行对应含义:
+ * 字段名
+ * 字段
+ * 必填
+ * 示例值
+ * 类型
+ * 说明
+ * Created by Binary Wang on 2016-11-28.
+ * @author binarywang(Binary Wang)
+ *
+ */
+public class WxPayRedpackQueryResult extends WxPayBaseResult {
+
+ /**
+ *
+ * 商户订单号
+ * mch_billno
+ * 是
+ * 10000098201411111234567890
+ * String(28)
+ * 商户使用查询API填写的商户单号的原路返回
+ *
+ */
+ @XStreamAlias("mch_billno")
+ private String mchBillNo;
+
+ /**
+ *
+ * 红包单号
+ * detail_id
+ * 是
+ * 1000000000201503283103439304
+ * String(32)
+ * 使用API发放现金红包时返回的红包单号
+ *
+ */
+ @XStreamAlias("detail_id")
+ private String detailId;
+
+ /**
+ *
+ * 红包状态
+ * status
+ * 是
+ * RECEIVED
+ * string(16)
+ * SENDING:发放中,
+ * SENT:已发放待领取,
+ * FAILED:发放失败,
+ * RECEIVED:已领取,
+ * RFUND_ING:退款中,
+ * REFUND:已退款
+ *
+ */
+ @XStreamAlias("status")
+ private String status;
+
+ /**
+ *
+ * 发放类型
+ * send_type
+ * 是
+ * API
+ * String(32)
+ * API:通过API接口发放,
+ * UPLOAD:通过上传文件方式发放,
+ * ACTIVITY:通过活动方式发放
+ *
+ */
+ @XStreamAlias("send_type")
+ private String sendType;
+
+ /**
+ *
+ * 红包类型
+ * hb_type
+ * 是
+ * GROUP
+ * String(32)
+ * GROUP:裂变红包,
+ * NORMAL:普通红包
+ *
+ */
+ @XStreamAlias("hb_type")
+ private String hbType;
+
+ /**
+ *
+ * 红包个数
+ * total_num
+ * 是
+ * 1
+ * int
+ * 红包个数
+ *
+ */
+ @XStreamAlias("total_num")
+ private Integer totalNum;
+
+ /**
+ *
+ * 红包金额
+ * total_amount
+ * 是
+ * 5000
+ * int
+ * 红包总金额(单位分)
+ *
+ */
+ @XStreamAlias("total_amount")
+ private Integer totalAmount;
+
+ /**
+ *
+ * 失败原因
+ * reason
+ * 否
+ * 余额不足
+ * String(32)
+ * 发送失败原因
+ *
+ */
+ @XStreamAlias("reason")
+ private String reason;
+
+ /**
+ *
+ * 红包发送时间
+ * send_time
+ * 是
+ * 2015-04-21 20:00:00
+ * String(32)
+ * 红包的发送时间
+ *
+ */
+ @XStreamAlias("send_time")
+ private String sendTime;
+
+ /**
+ *
+ * 红包退款时间
+ * refund_time
+ * 否
+ * 2015-04-21 23:03:00
+ * String(32)
+ * 红包的退款时间(如果其未领取的退款)
+ *
+ */
+ @XStreamAlias("refund_time")
+ private String refundTime;
+
+ /**
+ *
+ * 红包退款金额
+ * refund_amount
+ * 否
+ * 8000
+ * Int
+ * 红包退款金额
+ *
+ */
+ @XStreamAlias("refund_amount")
+ private Integer refundAmount;
+
+ /**
+ *
+ * 祝福语
+ * wishing
+ * 否
+ * 新年快乐
+ * String(128)
+ * 祝福语
+ *
+ */
+ @XStreamAlias("wishing")
+ private String wishing;
+
+ /**
+ *
+ * 活动描述
+ * remark
+ * 否
+ * 新年红包
+ * String(256)
+ * 活动描述,低版本微信可见
+ *
+ */
+ @XStreamAlias("remark")
+ private String remark;
+
+ /**
+ *
+ * 活动名称
+ * act_name
+ * 否
+ * 新年红包
+ * String(32)
+ * 发红包的活动名称
+ *
+ */
+ @XStreamAlias("act_name")
+ private String actName;
+
+ /**
+ *
+ * 裂变红包领取列表
+ * hblist
+ * 否
+ *
+ *
+ * 裂变红包的领取列表
+ *
+ */
+ @XStreamAlias("hblist")
+ private String hblist;
+
+ /**
+ *
+ * 领取红包的Openid
+ * openid
+ * 是
+ * ohO4GtzOAAYMp2yapORH3dQB3W18
+ * String(32)
+ * 领取红包的openid
+ *
+ */
+ @XStreamAlias("openid")
+ private String openid;
+
+ /**
+ *
+ * 金额
+ * amount
+ * 是
+ * 100
+ * int
+ * 领取金额
+ *
+ */
+ @XStreamAlias("amount")
+ private Integer amount;
+
+ /**
+ *
+ * 接收时间
+ * rcv_time
+ * 是
+ * 2015-04-21 20:00:00
+ * String(32)
+ * 领取红包的时间
+ *
+ */
+ @XStreamAlias("rcv_time")
+ private String receiveTime;
+
+ public String getMchBillNo() {
+ return mchBillNo;
+ }
+
+ public void setMchBillNo(String mchBillNo) {
+ this.mchBillNo = mchBillNo;
+ }
+
+ public String getDetailId() {
+ return detailId;
+ }
+
+ public void setDetailId(String detailId) {
+ this.detailId = detailId;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getSendType() {
+ return sendType;
+ }
+
+ public void setSendType(String sendType) {
+ this.sendType = sendType;
+ }
+
+ public String getHbType() {
+ return hbType;
+ }
+
+ public void setHbType(String hbType) {
+ this.hbType = hbType;
+ }
+
+ public Integer getTotalNum() {
+ return totalNum;
+ }
+
+ public void setTotalNum(Integer totalNum) {
+ this.totalNum = totalNum;
+ }
+
+ public Integer getTotalAmount() {
+ return totalAmount;
+ }
+
+ public void setTotalAmount(Integer totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+
+ public String getSendTime() {
+ return sendTime;
+ }
+
+ public void setSendTime(String sendTime) {
+ this.sendTime = sendTime;
+ }
+
+ public String getRefundTime() {
+ return refundTime;
+ }
+
+ public void setRefundTime(String refundTime) {
+ this.refundTime = refundTime;
+ }
+
+ public Integer getRefundAmount() {
+ return refundAmount;
+ }
+
+ public void setRefundAmount(Integer refundAmount) {
+ this.refundAmount = refundAmount;
+ }
+
+ public String getWishing() {
+ return wishing;
+ }
+
+ public void setWishing(String wishing) {
+ this.wishing = wishing;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+
+ public String getActName() {
+ return actName;
+ }
+
+ public void setActName(String actName) {
+ this.actName = actName;
+ }
+
+ public String getHblist() {
+ return hblist;
+ }
+
+ public void setHblist(String hblist) {
+ this.hblist = hblist;
+ }
+
+ public String getOpenid() {
+ return openid;
+ }
+
+ public void setOpenid(String openid) {
+ this.openid = openid;
+ }
+
+ public Integer getAmount() {
+ return amount;
+ }
+
+ public void setAmount(Integer amount) {
+ this.amount = amount;
+ }
+
+ public String getReceiveTime() {
+ return receiveTime;
+ }
+
+ public void setReceiveTime(String receiveTime) {
+ this.receiveTime = receiveTime;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java
new file mode 100644
index 00000000..43028846
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/pay/result/WxPayRefundQueryResult.java
@@ -0,0 +1,488 @@
+package me.chanjar.weixin.mp.bean.pay.result;
+
+import com.google.common.collect.Lists;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import java.util.List;
+
+/**
+ *
+ * Created by Binary Wang on 2016-11-24.
+ * @author binarywang(Binary Wang)
+ *
+ */
+@XStreamAlias("xml")
+public class WxPayRefundQueryResult extends WxPayBaseResult {
+ /**
+ *
+ * 设备号
+ * device_info
+ * 否
+ * String(32)
+ * 013467007045764
+ * 终端设备号
+ */
+ @XStreamAlias("device_info")
+ private String deviceInfo;
+
+ /**
+ *
+ * 微信订单号
+ * transaction_id
+ * 是
+ * String(32)
+ * 1217752501201407033233368018
+ * 微信订单号
+ */
+ @XStreamAlias("transaction_id")
+ private String transactionId;
+
+ /**
+ *
+ * 商户订单号
+ * out_trade_no
+ * 是
+ * String(32)
+ * 1217752501201407033233368018
+ * 商户系统内部的订单号
+ */
+ @XStreamAlias("out_trade_no")
+ private String outTradeNo;
+
+ /**
+ *
+ * 订单金额
+ * total_fee
+ * 是
+ * Int
+ * 100
+ * 订单总金额,单位为分,只能为整数,详见支付金额
+ */
+ @XStreamAlias("total_fee")
+ private Integer totalFee;
+
+ /**
+ *
+ * 应结订单金额
+ * settlement_total_fee
+ * 否
+ * Int
+ * 100
+ * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
+ */
+ @XStreamAlias("settlement_total_fee")
+ private Integer settlementTotalFee;
+
+ /**
+ *
+ * 货币种类
+ * fee_type
+ * 否
+ * String(8)
+ * CNY
+ * 订单金额货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+ */
+ @XStreamAlias("fee_type")
+ private String feeType;
+
+ /**
+ *
+ * 现金支付金额
+ * cash_fee
+ * 是
+ * Int
+ * 100
+ * 现金支付金额,单位为分,只能为整数,详见支付金额
+ */
+ @XStreamAlias("cash_fee")
+ private Integer cashFee;
+
+ /**
+ *
+ * 退款笔数
+ * refund_count
+ * 是
+ * Int
+ * 1
+ * 退款记录数
+ */
+ @XStreamAlias("refund_count")
+ private Integer refundCount;
+
+ private List refundRecords;
+
+ public String getDeviceInfo() {
+ return deviceInfo;
+ }
+
+ public void setDeviceInfo(String deviceInfo) {
+ this.deviceInfo = deviceInfo;
+ }
+
+ public String getTransactionId() {
+ return transactionId;
+ }
+
+ public void setTransactionId(String transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ public String getOutTradeNo() {
+ return outTradeNo;
+ }
+
+ public void setOutTradeNo(String outTradeNo) {
+ this.outTradeNo = outTradeNo;
+ }
+
+ public Integer getTotalFee() {
+ return totalFee;
+ }
+
+ public void setTotalFee(Integer totalFee) {
+ this.totalFee = totalFee;
+ }
+
+ public Integer getSettlementTotalFee() {
+ return settlementTotalFee;
+ }
+
+ public void setSettlementTotalFee(Integer settlementTotalFee) {
+ this.settlementTotalFee = settlementTotalFee;
+ }
+
+ public String getFeeType() {
+ return feeType;
+ }
+
+ public void setFeeType(String feeType) {
+ this.feeType = feeType;
+ }
+
+ public Integer getCashFee() {
+ return cashFee;
+ }
+
+ public void setCashFee(Integer cashFee) {
+ this.cashFee = cashFee;
+ }
+
+ public Integer getRefundCount() {
+ return refundCount;
+ }
+
+ public void setRefundCount(Integer refundCount) {
+ this.refundCount = refundCount;
+ }
+
+ public List getRefundRecords() {
+ return refundRecords;
+ }
+
+ public void setRefundRecords(List refundRecords) {
+ this.refundRecords = refundRecords;
+ }
+
+ public void composeRefundRecords(String xmlString) {
+ if (this.refundCount != null && this.refundCount > 0) {
+ this.refundRecords = Lists.newArrayList();
+ //TODO 暂时待实现
+ }
+ }
+
+ public static class RefundRecord {
+ /**
+ *
+ * 商户退款单号
+ * out_refund_no_$n
+ * 是
+ * String(32)
+ * 1217752501201407033233368018
+ * 商户退款单号
+ *
+ */
+ @XStreamAlias("out_refund_no")
+ private String outRefundNo;
+
+ /**
+ *
+ * 微信退款单号
+ * refund_id_$n
+ * 是
+ * String(28)
+ * 1217752501201407033233368018
+ * 微信退款单号
+ *
+ */
+ @XStreamAlias("refund_id")
+ private String refundId;
+
+ /**
+ *
+ * 退款渠道
+ * refund_channel_$n
+ * 否
+ * String(16)
+ * ORIGINAL
+ * ORIGINAL—原路退款 BALANCE—退回到余额
+ *
+ */
+ @XStreamAlias("refund_channel")
+ private String refundChannel;
+
+ /**
+ *
+ * 申请退款金额
+ * refund_fee_$n
+ * 是
+ * Int
+ * 100
+ * 退款总金额,单位为分,可以做部分退款
+ *
+ */
+ @XStreamAlias("refund_fee")
+ private String refundFee;
+
+ /**
+ *
+ * 退款金额
+ * settlement_refund_fee_$n
+ * 否
+ * Int
+ * 100
+ * 退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额
+ *
+ */
+ @XStreamAlias("settlement_refund_fee")
+ private String settlementRefundFee;
+
+ /**
+ *
+ * 退款资金来源
+ * refund_account
+ * 否
+ * String(30)
+ * REFUND_SOURCE_RECHARGE_FUNDS
+ * REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款/基本账户, REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款
+ *
+ */
+ @XStreamAlias("refund_account")
+ private String refundAccount;
+
+ /**
+ *
+ * 代金券类型
+ * coupon_type_$n
+ * 否
+ * Int
+ * CASH
+ * CASH--充值代金券 , NO_CASH---非充值代金券。订单使用代金券时有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_$0
+ *
+ */
+ @XStreamAlias("coupon_type")
+ private String couponType;
+
+ /**
+ *
+ * 代金券退款金额
+ * coupon_refund_fee_$n
+ * 否
+ * Int
+ * 100
+ * 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
+ *
+ */
+ @XStreamAlias("coupon_refund_fee")
+ private String couponRefundFee;
+
+ /**
+ *
+ * 退款代金券使用数量
+ * coupon_refund_count_$n
+ * 否
+ * Int
+ * 1
+ * 退款代金券使用数量 ,$n为下标,从0开始编号
+ *
+ */
+ @XStreamAlias("coupon_refund_count")
+ private String couponRefundCount;
+
+ private List refundCoupons;
+
+ /**
+ *
+ * 退款状态
+ * refund_status_$n
+ * 是
+ * String(16)
+ * SUCCESS
+ * 退款状态:
+ * SUCCESS—退款成功,
+ * FAIL—退款失败,
+ * PROCESSING—退款处理中,
+ * CHANGE—转入代发,
+ * 退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转账的方式进行退款。
+ *
+ */
+ @XStreamAlias("refund_status")
+ private String refundStatus;
+ /**
+ *
+ * 退款入账账户
+ * refund_recv_accout_$n
+ * 是
+ * String(64)
+ * 招商银行信用卡0403
+ * 取当前退款单的退款入账方,1)退回银行卡:{银行名称}{卡类型}{卡尾号},2)退回支付用户零钱:支付用户零钱
+ *
+ */
+ @XStreamAlias("refund_recv_accout")
+ private String refundRecvAccout;
+
+ public String getOutRefundNo() {
+ return outRefundNo;
+ }
+
+ public void setOutRefundNo(String outRefundNo) {
+ this.outRefundNo = outRefundNo;
+ }
+
+ public String getRefundId() {
+ return refundId;
+ }
+
+ public void setRefundId(String refundId) {
+ this.refundId = refundId;
+ }
+
+ public String getRefundChannel() {
+ return refundChannel;
+ }
+
+ public void setRefundChannel(String refundChannel) {
+ this.refundChannel = refundChannel;
+ }
+
+ public String getRefundFee() {
+ return refundFee;
+ }
+
+ public void setRefundFee(String refundFee) {
+ this.refundFee = refundFee;
+ }
+
+ public String getSettlementRefundFee() {
+ return settlementRefundFee;
+ }
+
+ public void setSettlementRefundFee(String settlementRefundFee) {
+ this.settlementRefundFee = settlementRefundFee;
+ }
+
+ public String getRefundAccount() {
+ return refundAccount;
+ }
+
+ public void setRefundAccount(String refundAccount) {
+ this.refundAccount = refundAccount;
+ }
+
+ public String getCouponType() {
+ return couponType;
+ }
+
+ public void setCouponType(String couponType) {
+ this.couponType = couponType;
+ }
+
+ public String getCouponRefundFee() {
+ return couponRefundFee;
+ }
+
+ public void setCouponRefundFee(String couponRefundFee) {
+ this.couponRefundFee = couponRefundFee;
+ }
+
+ public String getCouponRefundCount() {
+ return couponRefundCount;
+ }
+
+ public void setCouponRefundCount(String couponRefundCount) {
+ this.couponRefundCount = couponRefundCount;
+ }
+
+ public List getRefundCoupons() {
+ return refundCoupons;
+ }
+
+ public void setRefundCoupons(List refundCoupons) {
+ this.refundCoupons = refundCoupons;
+ }
+
+ public String getRefundStatus() {
+ return refundStatus;
+ }
+
+ public void setRefundStatus(String refundStatus) {
+ this.refundStatus = refundStatus;
+ }
+
+ public String getRefundRecvAccout() {
+ return refundRecvAccout;
+ }
+
+ public void setRefundRecvAccout(String refundRecvAccout) {
+ this.refundRecvAccout = refundRecvAccout;
+ }
+
+ public static class RefundCoupon {
+ /**
+ *
+ * 退款代金券批次ID
+ * coupon_refund_batch_id_$n_$m
+ * 否
+ * String(20)
+ * 100
+ * 退款代金券批次ID ,$n为下标,$m为下标,从0开始编号
+ *
+ */
+ @XStreamAlias("coupon_refund_batch_id")
+ private String couponRefundBatchId;
+
+ /**
+ *
+ * 退款代金券ID
+ * coupon_refund_id_$n_$m
+ * 否
+ * String(20)
+ * 10000
+ * 退款代金券ID, $n为下标,$m为下标,从0开始编号
+ *
+ */
+ @XStreamAlias("coupon_refund_id")
+ private String couponRefundId;
+
+ /**
+ *
+ * 单个退款代金券支付金额
+ * coupon_refund_fee_$n_$m
+ * 否
+ * Int
+ * 100
+ * 单个退款代金券支付金额, $n为下标,$m为下标,从0开始编号
+ *
+ */
+ @XStreamAlias("coupon_refund_fee")
+ private String couponRefundFee;
+
+ public RefundCoupon(String couponRefundBatchId, String couponRefundId, String couponRefundFee) {
+ this.couponRefundBatchId = couponRefundBatchId;
+ this.couponRefundId = couponRefundId;
+ this.couponRefundFee = couponRefundFee;
+ }
+ }
+
+ }
+}
+
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java
index 106e5fb6..df8e708d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java
@@ -1,18 +1,20 @@
package me.chanjar.weixin.mp.bean.template;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-
+/**
+ * 参考 http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN 发送模板消息接口部分
+ */
public class WxMpTemplateMessage implements Serializable {
private static final long serialVersionUID = 5063374783759519418L;
private String toUser;
private String templateId;
private String url;
- private String topColor;
private List data = new ArrayList<>();
public String getToUser() {
@@ -39,14 +41,6 @@ public class WxMpTemplateMessage implements Serializable {
this.url = url;
}
- public String getTopColor() {
- return this.topColor;
- }
-
- public void setTopColor(String topColor) {
- this.topColor = topColor;
- }
-
public List getData() {
return this.data;
}
@@ -71,7 +65,6 @@ public class WxMpTemplateMessage implements Serializable {
private String toUser;
private String templateId;
private String url;
- private String topColor;
private List data = new ArrayList<>();
public WxMpTemplateMessageBuilder toUser(String toUser) {
@@ -89,11 +82,6 @@ public class WxMpTemplateMessage implements Serializable {
return this;
}
- public WxMpTemplateMessageBuilder topColor(String topColor) {
- this.topColor = topColor;
- return this;
- }
-
public WxMpTemplateMessageBuilder data(List data) {
this.data = data;
return this;
@@ -103,7 +91,6 @@ public class WxMpTemplateMessage implements Serializable {
this.toUser(origin.toUser);
this.templateId(origin.templateId);
this.url(origin.url);
- this.topColor(origin.topColor);
this.data(origin.data);
return this;
}
@@ -113,7 +100,6 @@ public class WxMpTemplateMessage implements Serializable {
m.toUser = this.toUser;
m.templateId = this.templateId;
m.url = this.url;
- m.topColor = this.topColor;
m.data = this.data;
return m;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java
index 4e263020..5cc0d9c8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java
@@ -28,9 +28,6 @@ public class WxMpTemplateMessageGsonAdapter implements JsonSerializer, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
+public class XStreamTransformer {
+ private static final Map, XStream> CLASS_2_XSTREAM_INSTANCE = new HashMap<>();
+
+ static {
+ registerClass(WxMpXmlMessage.class);
+ registerClass(WxMpXmlOutMusicMessage.class);
+ registerClass(WxMpXmlOutNewsMessage.class);
+ registerClass(WxMpXmlOutTextMessage.class);
+ registerClass(WxMpXmlOutImageMessage.class);
+ registerClass(WxMpXmlOutVideoMessage.class);
+ registerClass(WxMpXmlOutVoiceMessage.class);
+ registerClass(WxMpXmlOutTransferKefuMessage.class);
+ }
/**
* xml -> pojo
@@ -36,16 +36,6 @@ public class XStreamTransformer {
return object;
}
- /**
- * 注册扩展消息的解析器
- * @param clz 类型
- * @param xStream xml解析器
- */
- public static void register(Class> clz, XStream xStream) {
- CLASS_2_XSTREAM_INSTANCE.put(clz,xStream);
- }
-
-
/**
* pojo -> xml
*/
@@ -53,83 +43,44 @@ public class XStreamTransformer {
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
}
- private static Map, XStream> configXStreamInstance() {
- Map, XStream> map = new HashMap<>();
- map.put(WxMpXmlMessage.class, config_WxMpXmlMessage());
- map.put(WxMpXmlOutMusicMessage.class, config_WxMpXmlOutMusicMessage());
- map.put(WxMpXmlOutNewsMessage.class, config_WxMpXmlOutNewsMessage());
- map.put(WxMpXmlOutTextMessage.class, config_WxMpXmlOutTextMessage());
- map.put(WxMpXmlOutImageMessage.class, config_WxMpXmlOutImageMessage());
- map.put(WxMpXmlOutVideoMessage.class, config_WxMpXmlOutVideoMessage());
- map.put(WxMpXmlOutVoiceMessage.class, config_WxMpXmlOutVoiceMessage());
- map.put(WxMpXmlOutTransferKefuMessage.class, config_WxMpXmlOutTransferCustomerServiceMessage());
-
- return map;
- }
-
- private static XStream config_WxMpXmlMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlMessage.class);
- xstream.processAnnotations(WxMpXmlMessage.ScanCodeInfo.class);
- xstream.processAnnotations(WxMpXmlMessage.SendPicsInfo.class);
- xstream.processAnnotations(WxMpXmlMessage.SendPicsInfo.Item.class);
- xstream.processAnnotations(WxMpXmlMessage.SendLocationInfo.class);
-
- xstream.aliasField("MsgID", WxMpXmlMessage.class, "msgId");
- return xstream;
- }
-
- private static XStream config_WxMpXmlOutImageMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutImageMessage.class);
- return xstream;
- }
-
- private static XStream config_WxMpXmlOutNewsMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutNewsMessage.class);
- xstream.processAnnotations(WxMpXmlOutNewsMessage.Item.class);
- return xstream;
+ /**
+ * 注册扩展消息的解析器
+ *
+ * @param clz 类型
+ * @param xStream xml解析器
+ */
+ public static void register(Class> clz, XStream xStream) {
+ CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
}
- private static XStream config_WxMpXmlOutMusicMessage() {
+ /**
+ * 会自动注册该类及其子类
+ * @param clz 要注册的类
+ */
+ public static void registerClass(Class> clz) {
XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutMusicMessage.class);
- xstream.processAnnotations(WxMpXmlOutMusicMessage.Music.class);
- return xstream;
+ xstream.processAnnotations(clz);
+ xstream.processAnnotations(getInnerClasses(clz));
+ register(clz, xstream);
}
- private static XStream config_WxMpXmlOutTextMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutTextMessage.class);
- return xstream;
- }
+ private static Class>[] getInnerClasses(Class> clz) {
+ Class>[] innerClasses = clz.getClasses();
+ if (innerClasses == null) {
+ return null;
+ }
- private static XStream config_WxMpXmlOutVideoMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutVideoMessage.class);
- xstream.processAnnotations(WxMpXmlOutVideoMessage.Video.class);
- return xstream;
- }
+ List> result = new ArrayList<>();
+ result.addAll(Arrays.asList(innerClasses));
+ for (Class> inner : innerClasses) {
+ Class>[] innerClz = getInnerClasses(inner);
+ if (innerClz == null) {
+ continue;
+ }
- private static XStream config_WxMpXmlOutVoiceMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutVoiceMessage.class);
- return xstream;
- }
+ result.addAll(Arrays.asList(innerClz));
+ }
- private static XStream config_WxMpXmlOutTransferCustomerServiceMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxMpXmlOutMessage.class);
- xstream.processAnnotations(WxMpXmlOutTransferKefuMessage.class);
- xstream.processAnnotations(WxMpXmlOutTransferKefuMessage.TransInfo.class);
- return xstream;
+ return result.toArray(new Class>[0]);
}
-
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
index 310593c7..2b749b9f 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
@@ -1,15 +1,15 @@
package me.chanjar.weixin.mp.api;
-import java.io.IOException;
-import java.io.InputStream;
-
import com.google.inject.Binder;
import com.google.inject.Module;
import com.thoughtworks.xstream.XStream;
-
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.locks.ReentrantLock;
+
public class ApiTestModule implements Module {
@Override
@@ -18,6 +18,7 @@ public class ApiTestModule implements Module {
.getSystemResourceAsStream("test-config.xml")) {
WxXmlMpInMemoryConfigStorage config = this
.fromXml(WxXmlMpInMemoryConfigStorage.class, is1);
+ config.setAccessTokenLock(new ReentrantLock());
WxMpService wxService = new WxMpServiceImpl();
wxService.setWxMpConfigStorage(config);
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxXmlMpInMemoryConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxXmlMpInMemoryConfigStorage.java
index c9835a0a..75494efe 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxXmlMpInMemoryConfigStorage.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxXmlMpInMemoryConfigStorage.java
@@ -1,8 +1,9 @@
package me.chanjar.weixin.mp.api;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.apache.commons.lang3.builder.ToStringBuilder;
-import com.thoughtworks.xstream.annotations.XStreamAlias;
+import java.util.concurrent.locks.Lock;
@XStreamAlias("xml")
public class WxXmlMpInMemoryConfigStorage
@@ -50,4 +51,7 @@ public class WxXmlMpInMemoryConfigStorage
this.templateId = templateId;
}
-}
\ No newline at end of file
+ public void setAccessTokenLock(Lock lock){
+ super.accessTokenLock = lock;
+ }
+}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java
index f31a0e4b..a312b15d 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java
@@ -1,18 +1,17 @@
package me.chanjar.weixin.mp.api.impl;
-import me.chanjar.weixin.mp.api.WxMpService;
-import org.testng.Assert;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
-
import com.google.inject.Inject;
-
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.ApiTestModule;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
/**
* 测试菜单
@@ -28,11 +27,22 @@ public class WxMpMenuServiceImplTest {
protected WxMpService wxService;
@Test(dataProvider = "menu")
- public void testCreateMenu(WxMenu wxMenu) throws WxErrorException {
+ public void testMenuCreate(WxMenu wxMenu) throws WxErrorException {
System.out.println(wxMenu.toJson());
this.wxService.getMenuService().menuCreate(wxMenu);
}
+ @Test
+ public void testMenuTryMatch() throws Exception {
+ //TODO
+ }
+
+ @Test
+ public void testGetSelfMenuInfo() throws Exception {
+ WxMpGetSelfMenuInfoResult selfMenuInfo = this.wxService.getMenuService().getSelfMenuInfo();
+ System.out.println(selfMenuInfo);
+ }
+
@Test
public void testCreateMenu2() throws WxErrorException {
String a = "{\n"
@@ -77,15 +87,15 @@ public class WxMpMenuServiceImplTest {
this.wxService.getMenuService().menuCreate(menu);
}
- @Test(dependsOnMethods = { "testCreateMenu"})
- public void testGetMenu() throws WxErrorException {
+ @Test(dependsOnMethods = { "testMenuCreate"})
+ public void testMenuGet() throws WxErrorException {
WxMenu wxMenu = this.wxService.getMenuService().menuGet();
Assert.assertNotNull(wxMenu);
System.out.println(wxMenu.toJson());
}
- @Test(dependsOnMethods = { "testGetMenu"})
- public void testDeleteMenu() throws WxErrorException {
+ @Test(dependsOnMethods = { "testMenuGet"})
+ public void testMenuDelete() throws WxErrorException {
this.wxService.getMenuService().menuDelete();
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java
index b4e22f11..7b2a9dea 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpPayServiceImplTest.java
@@ -9,9 +9,7 @@ import me.chanjar.weixin.mp.bean.pay.request.WxEntPayRequest;
import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest;
import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest;
import me.chanjar.weixin.mp.bean.pay.request.WxPayUnifiedOrderRequest;
-import me.chanjar.weixin.mp.bean.pay.result.WxPayRefundResult;
-import me.chanjar.weixin.mp.bean.pay.result.WxPaySendRedpackResult;
-import me.chanjar.weixin.mp.bean.pay.result.WxPayUnifiedOrderResult;
+import me.chanjar.weixin.mp.bean.pay.result.*;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -20,6 +18,7 @@ import java.io.File;
/**
* 测试支付相关接口
* Created by Binary Wang on 2016/7/28.
+ *
* @author binarywang (https://github.com/binarywang)
*/
@Test
@@ -34,6 +33,9 @@ public class WxMpPayServiceImplTest {
}
+ /**
+ * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refund(WxPayRefundRequest, File)} .
+ */
@Test
public void testRefund() throws Exception {
WxPayRefundRequest request = new WxPayRefundRequest();
@@ -46,33 +48,64 @@ public class WxMpPayServiceImplTest {
System.err.println(result);
}
+
+ /**
+ * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refundQuery(String, String, String, String)} .
+ */
+ @Test
+ public void testRefundQuery() throws Exception {
+ WxPayRefundQueryResult result = this.wxService.getPayService().refundQuery("1", "", "", "");
+ result = this.wxService.getPayService().refundQuery("", "2", "", "");
+ System.err.println(result);
+ result = this.wxService.getPayService().refundQuery("", "", "3", "");
+ System.err.println(result);
+ result = this.wxService.getPayService().refundQuery("", "", "", "4");
+ System.err.println(result);
+ //测试四个参数都填的情况,应该报异常的
+ result = this.wxService.getPayService().refundQuery("1", "2", "3", "4");
+ System.err.println(result);
+ }
+
@Test
public void testCheckJSSDKCallbackDataSignature() throws Exception {
}
+ /**
+ * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#sendRedpack(WxPaySendRedpackRequest, File)} .
+ */
@Test
public void testSendRedpack() throws Exception {
WxPaySendRedpackRequest request = new WxPaySendRedpackRequest();
request.setActName("abc");
request.setClientIp("aaa");
- request.setMchBillno("aaaa");
+ request.setMchBillNo("aaaa");
request
- .setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid());
+ .setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid());
File keyFile = new File("E:\\dlt.p12");
WxPaySendRedpackResult redpackResult = this.wxService.getPayService().sendRedpack(request, keyFile);
System.err.println(redpackResult);
}
+ /**
+ * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryRedpack(String, File)}.
+ */
+ @Test
+ public void testQueryRedpack() throws Exception {
+ File keyFile = new File("E:\\dlt.p12");
+ WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa", keyFile);
+ System.err.println(redpackResult);
+ }
+
/**
* Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#unifiedOrder(WxPayUnifiedOrderRequest)}.
*/
@Test
public void testUnifiedOrder() throws WxErrorException {
WxPayUnifiedOrderResult result = this.wxService.getPayService()
- .unifiedOrder(WxPayUnifiedOrderRequest.builder().body("1111111")
- .totalFee(1).spbillCreateIp("111111").notifyURL("111111")
- .tradeType("JSAPI").openid("122").outTradeNo("111111").build());
+ .unifiedOrder(WxPayUnifiedOrderRequest.builder().body("1111111")
+ .totalFee(1).spbillCreateIp("111111").notifyURL("111111")
+ .tradeType("JSAPI").openid("122").outTradeNo("111111").build());
System.err.println(result);
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java
index 9b50d5df..b37278e2 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java
@@ -9,6 +9,7 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplate;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import org.apache.commons.lang3.RandomStringUtils;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -28,7 +29,7 @@ public class WxMpTemplateMsgServiceImplTest {
@Inject
protected WxMpService wxService;
- @Test(invocationCount = 10, threadPoolSize = 10)
+ @Test(invocationCount = 5, threadPoolSize = 3)
public void testSendTemplateMsg() throws WxErrorException {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.SSS");
@@ -38,7 +39,10 @@ public class WxMpTemplateMsgServiceImplTest {
.toUser(configStorage.getOpenid())
.templateId(configStorage.getTemplateId()).build();
templateMessage.addWxMpTemplateData(
- new WxMpTemplateData("first", dateFormat.format(new Date())));
+ new WxMpTemplateData("first", dateFormat.format(new Date()),"#FF00FF"));
+ templateMessage.addWxMpTemplateData(
+ new WxMpTemplateData("remark", RandomStringUtils.randomAlphanumeric(100), "#FF00FF"));
+ templateMessage.setUrl(" ");
String msgId = this.wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
Assert.assertNotNull(msgId);
System.out.println(msgId);
diff --git a/weixin-java-osgi/pom.xml b/weixin-java-osgi/pom.xml
index 7f4a5973..ca14e476 100644
--- a/weixin-java-osgi/pom.xml
+++ b/weixin-java-osgi/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
weixin-java-parent
- 2.3.0
+ 2.4.0
weixin-java-osgi