From 5b49c63d148e8f81c479217933135d4c2d4b44fe Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Tue, 27 Jan 2015 14:45:11 +0800 Subject: [PATCH] =?UTF-8?q?issue=20#91=20=E6=B7=BB=E5=8A=A0=E4=BC=81?= =?UTF-8?q?=E4=B8=9A=E5=8F=B7JS=5FAPI=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WxErrorExceptionHandler.java | 2 +- .../WxMessageDuplicateChecker.java | 2 +- .../WxMessageInMemoryDuplicateChecker.java | 2 +- .../weixin/common/bean/WxJsapiSignature.java | 4 +- .../common/util/LogExceptionHandler.java | 1 + .../weixin/common/util/RandomUtils.java | 17 +++++ ...WxMessageInMemoryDuplicateCheckerTest.java | 1 + .../weixin/cp/api/WxCpConfigStorage.java | 14 ++++ .../cp/api/WxCpInMemoryConfigStorage.java | 36 ++++++++++ .../weixin/cp/api/WxCpMessageRouter.java | 12 ++-- .../weixin/cp/api/WxCpMessageRouterRule.java | 2 +- .../weixin/cp/api/WxCpServiceImpl.java | 60 +++++++++++++++- .../java/TestNonAtomicLongAssignment.java | 68 +++++++++++++++++++ .../mp/api/WxMpInMemoryConfigStorage.java | 13 +++- .../weixin/mp/api/WxMpMessageRouter.java | 12 ++-- .../weixin/mp/api/WxMpMessageRouterRule.java | 2 +- .../me/chanjar/weixin/mp/api/WxMpService.java | 5 +- .../weixin/mp/api/WxMpServiceImpl.java | 21 ++---- 18 files changed, 232 insertions(+), 42 deletions(-) rename weixin-java-common/src/main/java/me/chanjar/weixin/common/{util => api}/WxErrorExceptionHandler.java (82%) rename weixin-java-common/src/main/java/me/chanjar/weixin/common/{util => api}/WxMessageDuplicateChecker.java (96%) rename weixin-java-common/src/main/java/me/chanjar/weixin/common/{util => api}/WxMessageInMemoryDuplicateChecker.java (98%) rename weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpJsapiSignature.java => weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java (91%) create mode 100644 weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java create mode 100644 weixin-java-mp/src/main/java/TestNonAtomicLongAssignment.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxErrorExceptionHandler.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java similarity index 82% rename from weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxErrorExceptionHandler.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java index 70940aef..9abda804 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxErrorExceptionHandler.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.common.util; +package me.chanjar.weixin.common.api; import me.chanjar.weixin.common.exception.WxErrorException; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java similarity index 96% rename from weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java index 1abe588b..6cdb689a 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.common.util; +package me.chanjar.weixin.common.api; /** *
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java
similarity index 98%
rename from weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java
rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java
index ae0e0623..1efc7a27 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.common.util;
+package me.chanjar.weixin.common.api;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpJsapiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java
similarity index 91%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpJsapiSignature.java
rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java
index a09c4082..c01d6c61 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpJsapiSignature.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java
@@ -1,9 +1,9 @@
-package me.chanjar.weixin.mp.bean.result;
+package me.chanjar.weixin.common.bean;
 
 /**
  * jspai signature
  */
-public class WxMpJsapiSignature {
+public class WxJsapiSignature {
 
   private String noncestr;
 
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java
index 1fa1af75..a512e599 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java
@@ -1,5 +1,6 @@
 package me.chanjar.weixin.common.util;
 
+import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
 import me.chanjar.weixin.common.exception.WxErrorException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java
new file mode 100644
index 00000000..bbb11992
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java
@@ -0,0 +1,17 @@
+package me.chanjar.weixin.common.util;
+
+public class RandomUtils {
+
+  private static final String RANDOM_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+  private static final java.util.Random RANDOM = new java.util.Random();
+
+  public static String getRandomStr() {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < 16; i++) {
+      sb.append(RANDOM_STR.charAt(RANDOM.nextInt(RANDOM_STR.length())));
+    }
+    return sb.toString();
+  }
+
+}
diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java
index 28642c44..7369d637 100644
--- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java
+++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java
@@ -1,5 +1,6 @@
 package me.chanjar.weixin.common.util;
 
+import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
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 44123a36..94029841 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
@@ -22,6 +22,20 @@ public interface WxCpConfigStorage {
 
   public void updateAccessToken(String accessToken, int expiresIn);
 
+  public String getJsapiTicket();
+
+  public boolean isJsapiTicketExpired();
+
+  /**
+   * 强制将jsapi ticket过期掉
+   */
+  public void expireJsapiTicket();
+
+  /**
+   * 应该是线程安全的
+   * @param jsapiTicket
+   */
+  public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
 
   public String getCorpId();
   
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 b7f662cd..59fc6f2a 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
@@ -25,6 +25,9 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
   protected volatile String http_proxy_username;
   protected volatile String http_proxy_password;
 
+  protected volatile String jsapiTicket;
+  protected volatile long jsapiTicketExpiresTime;
+
   public String getAccessToken() {
     return this.accessToken;
   }
@@ -46,6 +49,37 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
     this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
   }
 
+  @Override
+  public String getJsapiTicket() {
+    return jsapiTicket;
+  }
+
+  public void setJsapiTicket(String jsapiTicket) {
+    this.jsapiTicket = jsapiTicket;
+  }
+
+  public long getJsapiTicketExpiresTime() {
+    return jsapiTicketExpiresTime;
+  }
+
+  public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) {
+    this.jsapiTicketExpiresTime = jsapiTicketExpiresTime;
+  }
+
+  public boolean isJsapiTicketExpired() {
+    return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
+  }
+
+  public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+    this.jsapiTicket = jsapiTicket;
+    // 预留200秒的时间
+    this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
+  }
+
+  public void expireJsapiTicket() {
+    this.jsapiTicketExpiresTime = 0;
+  }
+
   public String getCorpId() {
     return this.corpId;
   }
@@ -153,6 +187,8 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
         ", http_proxy_port=" + http_proxy_port +
         ", http_proxy_username='" + http_proxy_username + '\'' +
         ", http_proxy_password='" + http_proxy_password + '\'' +
+        ", jsapiTicket='" + jsapiTicket + '\'' +
+        ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' +
         '}';
   }
 
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 52f16bf5..29798b91 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
@@ -5,9 +5,9 @@ import me.chanjar.weixin.common.session.InternalSessionManager;
 import me.chanjar.weixin.common.session.StandardSessionManager;
 import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.common.util.LogExceptionHandler;
-import me.chanjar.weixin.common.util.WxErrorExceptionHandler;
-import me.chanjar.weixin.common.util.WxMessageDuplicateChecker;
-import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker;
+import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
+import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
+import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
 import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
 import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
 import org.slf4j.Logger;
@@ -87,8 +87,8 @@ public class WxCpMessageRouter {
 
   /**
    * 
-   * 设置自定义的 {@link me.chanjar.weixin.common.util.WxMessageDuplicateChecker}
-   * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker}
+   * 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker}
+   * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker}
    * 
* @param messageDuplicateChecker */ @@ -109,7 +109,7 @@ public class WxCpMessageRouter { /** *
-   * 设置自定义的{@link me.chanjar.weixin.common.util.WxErrorExceptionHandler}
+   * 设置自定义的{@link me.chanjar.weixin.common.api.WxErrorExceptionHandler}
    * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler}
    * 
* @param exceptionHandler 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 7fb253c7..cf453938 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 @@ -2,7 +2,7 @@ package me.chanjar.weixin.cp.api; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.common.util.WxErrorExceptionHandler; +import me.chanjar.weixin.common.api.WxErrorExceptionHandler; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; 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 3f14a53c..3fc393b0 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 @@ -8,6 +8,7 @@ import com.google.gson.internal.Streams; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; @@ -15,6 +16,7 @@ import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.session.StandardSessionManager; import me.chanjar.weixin.common.session.WxSession; import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.StringUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.fs.FileUtils; @@ -44,6 +46,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.UUID; @@ -54,7 +57,12 @@ public class WxCpServiceImpl implements WxCpService { /** * 全局的是否正在刷新access token的锁 */ - protected static final Object GLOBAL_ACCESS_TOKEN_REFRESH_LOCK = new Object(); + protected final Object globalAccessTokenRefreshLock = new Object(); + + /** + * 全局的是否正在刷新jsapi_ticket的锁 + */ + protected final Object globalJsapiTicketRefreshLock = new Object(); protected WxCpConfigStorage wxCpConfigStorage; @@ -90,7 +98,7 @@ public class WxCpServiceImpl implements WxCpService { wxCpConfigStorage.expireAccessToken(); } if (wxCpConfigStorage.isAccessTokenExpired()) { - synchronized (GLOBAL_ACCESS_TOKEN_REFRESH_LOCK) { + synchronized (globalAccessTokenRefreshLock) { if (wxCpConfigStorage.isAccessTokenExpired()) { String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" + "&corpid=" + wxCpConfigStorage.getCorpId() @@ -121,6 +129,52 @@ public class WxCpServiceImpl implements WxCpService { return wxCpConfigStorage.getAccessToken(); } + public String getJsapiTicket() throws WxErrorException { + return getJsapiTicket(false); + } + + public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { + if (forceRefresh) { + wxCpConfigStorage.expireJsapiTicket(); + } + if (wxCpConfigStorage.isJsapiTicketExpired()) { + synchronized (globalJsapiTicketRefreshLock) { + if (wxCpConfigStorage.isJsapiTicketExpired()) { + String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi"; + String responseContent = execute(new SimpleGetRequestExecutor(), url, null); + JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); + int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); + wxCpConfigStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds); + } + } + } + return wxCpConfigStorage.getJsapiTicket(); + } + + public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String noncestr = RandomUtils.getRandomStr(); + String jsapiTicket = getJsapiTicket(false); + try { + String signature = SHA1.genWithAmple( + "jsapi_ticket=" + jsapiTicket, + "noncestr=" + noncestr, + "timestamp=" + timestamp, + "url=" + url + ); + WxJsapiSignature jsapiSignature = new WxJsapiSignature(); + jsapiSignature.setTimestamp(timestamp); + jsapiSignature.setNoncestr(noncestr); + jsapiSignature.setUrl(url); + jsapiSignature.setSignature(signature); + return jsapiSignature; + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + public void messageSend(WxCpMessage message) throws WxErrorException { String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send"; post(url, message.toJson()); @@ -477,7 +531,7 @@ public class WxCpServiceImpl implements WxCpService { * 42001 access_token超时 */ if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { - // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token + // 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token wxCpConfigStorage.expireAccessToken(); return execute(executor, uri, data); } diff --git a/weixin-java-mp/src/main/java/TestNonAtomicLongAssignment.java b/weixin-java-mp/src/main/java/TestNonAtomicLongAssignment.java new file mode 100644 index 00000000..e86d89fe --- /dev/null +++ b/weixin-java-mp/src/main/java/TestNonAtomicLongAssignment.java @@ -0,0 +1,68 @@ +/** + * Created by qianjia on 15/1/25. + */ +public class TestNonAtomicLongAssignment { + + private static final long HI = 1l << 32; + private static final long LO = 1l; + + private static final long TEST_NUMBER = HI | LO; + + private static long assignee = 0l; + + public static void main(String[] args) { + + Thread writer = new Thread(new Runnable() { + @Override + public void run() { + while (true) { + assignee = TEST_NUMBER; + } + } + }); + writer.setDaemon(true); + + Thread reader = new Thread(new Runnable() { + @Override + public void run() { + long i = 0; + while (true) { + i++; + long test = assignee; + if (test != TEST_NUMBER) { + System.out.print(i + " times:" + toBin(test)); + break; + } + } + } + }); + + // Thread worker = new Thread(new Runnable() { + // @Override + // public void run() { + // double d = 89009808877238948224343435452333323113131313133434434341212323232424243434335354232390490189190420928348910913094983.323334401928d; + // while(true) { + // Math.cbrt(d); + // d = d - 1l; + // } + // } + // }); + // worker.setDaemon(true); + // worker.start(); + + writer.start(); + reader.start(); + + } + + public static String toBin(long n) { + StringBuilder sb = new StringBuilder(Long.toBinaryString(n)); + int padding = 64 - sb.length(); + while (padding > 0) { + sb.insert(0, '0'); + padding--; + } + return sb.toString(); + } + +} 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 f1fb8fe6..3033d178 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 @@ -51,6 +51,18 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { return jsapiTicket; } + public void setJsapiTicket(String jsapiTicket) { + this.jsapiTicket = jsapiTicket; + } + + public long getJsapiTicketExpiresTime() { + return jsapiTicketExpiresTime; + } + + public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) { + this.jsapiTicketExpiresTime = jsapiTicketExpiresTime; + } + public boolean isJsapiTicketExpired() { return System.currentTimeMillis() > this.jsapiTicketExpiresTime; } @@ -167,5 +179,4 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + '}'; } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java index 1cd2f580..d98c6a4a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java @@ -5,9 +5,9 @@ import me.chanjar.weixin.common.session.InternalSessionManager; import me.chanjar.weixin.common.session.StandardSessionManager; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.LogExceptionHandler; -import me.chanjar.weixin.common.util.WxErrorExceptionHandler; -import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; -import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; +import me.chanjar.weixin.common.api.WxErrorExceptionHandler; +import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; +import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; import me.chanjar.weixin.mp.bean.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; import org.slf4j.Logger; @@ -87,8 +87,8 @@ public class WxMpMessageRouter { /** *
-   * 设置自定义的 {@link me.chanjar.weixin.common.util.WxMessageDuplicateChecker}
-   * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker}
+   * 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker}
+   * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker}
    * 
* @param messageDuplicateChecker */ @@ -109,7 +109,7 @@ public class WxMpMessageRouter { /** *
-   * 设置自定义的{@link me.chanjar.weixin.common.util.WxErrorExceptionHandler}
+   * 设置自定义的{@link me.chanjar.weixin.common.api.WxErrorExceptionHandler}
    * 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler}
    * 
* @param exceptionHandler diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouterRule.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouterRule.java index 95db8ab4..5f27dab0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouterRule.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouterRule.java @@ -2,7 +2,7 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.common.util.WxErrorExceptionHandler; +import me.chanjar.weixin.common.api.WxErrorExceptionHandler; import me.chanjar.weixin.mp.bean.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 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 7d1d6dcf..b2750871 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 @@ -1,10 +1,9 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxMenu; +import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.session.WxSession; -import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.mp.bean.*; import me.chanjar.weixin.mp.bean.result.*; @@ -86,7 +85,7 @@ public interface WxMpService { * @param url url * @return */ - public WxMpJsapiSignature createJsapiSignature(String url) throws WxErrorException; + public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; /** *
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
index 9f719140..f44ba14d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
@@ -7,11 +7,13 @@ import com.google.gson.reflect.TypeToken;
 import com.google.gson.stream.JsonReader;
 import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.bean.WxMenu;
+import me.chanjar.weixin.common.bean.WxJsapiSignature;
 import me.chanjar.weixin.common.bean.result.WxError;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
 import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.session.StandardSessionManager;
 import me.chanjar.weixin.common.session.WxSessionManager;
+import me.chanjar.weixin.common.util.RandomUtils;
 import me.chanjar.weixin.common.util.StringUtils;
 import me.chanjar.weixin.common.util.crypto.SHA1;
 import me.chanjar.weixin.common.util.fs.FileUtils;
@@ -42,15 +44,10 @@ import java.io.InputStream;
 import java.io.StringReader;
 import java.security.NoSuchAlgorithmException;
 import java.util.List;
-import java.util.Random;
 import java.util.UUID;
 
 public class WxMpServiceImpl implements WxMpService {
 
-  protected final String RANDOM_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-  protected final Random RANDOM = new Random();
-
   protected final Logger log = LoggerFactory.getLogger(WxMpServiceImpl.class);
 
   /**
@@ -148,9 +145,9 @@ public class WxMpServiceImpl implements WxMpService {
     return wxMpConfigStorage.getJsapiTicket();
   }
 
-  public WxMpJsapiSignature createJsapiSignature(String url) throws WxErrorException {
+  public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException {
     long timestamp = System.currentTimeMillis() / 1000;
-    String noncestr = getRandomStr();
+    String noncestr = RandomUtils.getRandomStr();
     String jsapiTicket = getJsapiTicket(false);
     try {
       String signature = SHA1.genWithAmple(
@@ -159,7 +156,7 @@ public class WxMpServiceImpl implements WxMpService {
           "timestamp=" + timestamp,
           "url=" + url
       );
-      WxMpJsapiSignature jsapiSignature = new WxMpJsapiSignature();
+      WxJsapiSignature jsapiSignature = new WxJsapiSignature();
       jsapiSignature.setTimestamp(timestamp);
       jsapiSignature.setNoncestr(noncestr);
       jsapiSignature.setUrl(url);
@@ -170,14 +167,6 @@ public class WxMpServiceImpl implements WxMpService {
     }
   }
 
-  protected String getRandomStr() {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < 16; i++) {
-      sb.append(RANDOM_STR.charAt(RANDOM.nextInt(RANDOM_STR.length())));
-    }
-    return sb.toString();
-  }
-
   public void customMessageSend(WxMpCustomMessage message) throws WxErrorException {
     String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
     execute(new SimplePostRequestExecutor(), url, message.toJson());