From 214e7e58fa07b6e1d41b6aa3ce88800c3995a69e Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 5 Aug 2018 19:51:41 +0800 Subject: [PATCH] =?UTF-8?q?#672=20=E5=B0=8F=E7=A8=8B=E5=BA=8F=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0jssdk=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/common/bean/WxJsapiSignature.java | 8 ++ .../wx/miniapp/api/WxMaJsapiService.java | 48 ++++++++++++ .../wx/miniapp/api/WxMaService.java | 9 +++ .../api/impl/WxMaJsapiServiceImpl.java | 75 +++++++++++++++++++ .../wx/miniapp/api/impl/WxMaServiceImpl.java | 16 ++-- .../wx/miniapp/config/WxMaConfig.java | 19 +++++ .../wx/miniapp/config/WxMaInMemoryConfig.java | 31 ++++++++ .../api/impl/WxMaJsapiServiceImplTest.java | 45 +++++++++++ .../wx/miniapp/test/TestConfig.java | 1 + 9 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java index 619f0a75..fb585d36 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java @@ -1,13 +1,21 @@ package me.chanjar.weixin.common.bean; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.Serializable; /** * jspai signature. + * + * @author chanjarster */ @Data +@Builder +@NoArgsConstructor +@AllArgsConstructor public class WxJsapiSignature implements Serializable { private static final long serialVersionUID = -1116808193154384804L; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java new file mode 100644 index 00000000..156fcbc1 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java @@ -0,0 +1,48 @@ +package cn.binarywang.wx.miniapp.api; + +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; + +/** + *
+ *  jsapi相关接口
+ *  Created by BinaryWang on 2018/8/5.
+ * 
+ * + * @author Binary Wang + */ +public interface WxMaJsapiService { + /** + * 获得jsapi_ticket的url + */ + String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi"; + + /** + * 获得jsapi_ticket,不强制刷新jsapi_ticket + * + * @see #getJsapiTicket(boolean) + */ + String getJsapiTicket() throws WxErrorException; + + /** + *
+   * 获得jsapi_ticket
+   * 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
+   * 
+ * + * @param forceRefresh 强制刷新 + */ + String getJsapiTicket(boolean forceRefresh) throws WxErrorException; + + /** + *
+   * 创建调用jsapi时所需要的签名
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
+   * 
+ */ + WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java index e89929ca..bc625ac0 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java @@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.api; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.config.WxMaConfig; +import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestExecutor; @@ -17,6 +18,7 @@ public interface WxMaService { String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session"; + /** * 获取登录后的session信息 * @@ -149,6 +151,13 @@ public interface WxMaService { */ WxMaCodeService getCodeService(); + /** + * 返回jsapi操作相关的 API服务类对象 + * + * @return WxMaJsapiService + */ + WxMaJsapiService getJsapiService(); + /** * 小程序修改服务器地址、成员管理 API * diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java new file mode 100644 index 00000000..8164db8b --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java @@ -0,0 +1,75 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaJsapiService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.RandomUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; + +import java.util.concurrent.locks.Lock; + +/** + *
+ *  Created by BinaryWang on 2018/8/5.
+ * 
+ * + * @author Binary Wang + */ +public class WxMaJsapiServiceImpl implements WxMaJsapiService { + private static final JsonParser JSON_PARSER = new JsonParser(); + + private WxMaService wxMaService; + + public WxMaJsapiServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public String getJsapiTicket() throws WxErrorException { + return getJsapiTicket(false); + } + + @Override + public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { + Lock lock = this.wxMaService.getWxMaConfig().getJsapiTicketLock(); + try { + lock.lock(); + if (forceRefresh) { + this.wxMaService.getWxMaConfig().expireJsapiTicket(); + } + + if (this.wxMaService.getWxMaConfig().isJsapiTicketExpired()) { + String responseContent = this.wxMaService.get(GET_JSAPI_TICKET_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.wxMaService.getWxMaConfig().updateJsapiTicket(jsapiTicket, expiresInSeconds); + } + } finally { + lock.unlock(); + } + return this.wxMaService.getWxMaConfig().getJsapiTicket(); + } + + @Override + public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String randomStr = RandomUtils.getRandomStr(); + String jsapiTicket = getJsapiTicket(false); + String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, + "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url); + return WxJsapiSignature + .builder() + .appId(this.wxMaService.getWxMaConfig().getAppid()) + .timestamp(timestamp) + .nonceStr(randomStr) + .url(url) + .signature(signature) + .build(); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java index be9dff69..7ee89cc8 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java @@ -1,14 +1,6 @@ package cn.binarywang.wx.miniapp.api.impl; -import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; -import cn.binarywang.wx.miniapp.api.WxMaCodeService; -import cn.binarywang.wx.miniapp.api.WxMaMediaService; -import cn.binarywang.wx.miniapp.api.WxMaMsgService; -import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.api.WxMaSettingService; -import cn.binarywang.wx.miniapp.api.WxMaTemplateService; -import cn.binarywang.wx.miniapp.api.WxMaUserService; +import cn.binarywang.wx.miniapp.api.*; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.config.WxMaConfig; import com.google.common.base.Joiner; @@ -58,6 +50,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp this.jsapiTicketExpiresTime; + } + + @Override + public void expireJsapiTicket() { + this.jsapiTicketExpiresTime = 0; + } + + @Override + public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { + this.jsapiTicket = jsapiTicket; + // 预留200秒的时间 + this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + } + @Override public void expireAccessToken() { this.expiresTime = 0; diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java new file mode 100644 index 00000000..07f4358d --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java @@ -0,0 +1,45 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
+ *  Created by BinaryWang on 2018/8/5.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaJsapiServiceImplTest { + @Inject + private WxMaService wxService; + @Inject + private WxMaConfig wxMaConfig; + + @Test + public void testGetJsapiTicket() throws WxErrorException { + assertThat(this.wxService.getJsapiService().getJsapiTicket()).isNotBlank(); + } + + @Test + public void testGetJsapiTicket1() throws WxErrorException { + assertThat(this.wxService.getJsapiService().getJsapiTicket(true)).isNotBlank(); + } + + @Test + public void testCreateJsapiSignature() throws WxErrorException { + final WxJsapiSignature jsapiSignature = this.wxService.getJsapiService().createJsapiSignature("http://www.qq.com"); + System.out.println(jsapiSignature); + assertThat(jsapiSignature).isNotNull(); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java index ee941ef3..6cebdeb2 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java @@ -54,6 +54,7 @@ public class TestConfig extends WxMaInMemoryConfig { this.templateId = templateId; } + @Override public void setAccessTokenLock(Lock lock) { super.accessTokenLock = lock; }