Skip to content

Commit 214e7e5

Browse files
committed
#672 小程序增加jssdk相关接口实现
1 parent 93db323 commit 214e7e5

File tree

9 files changed

+243
-9
lines changed

9 files changed

+243
-9
lines changed

weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java

+8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
package me.chanjar.weixin.common.bean;
22

3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
35
import lombok.Data;
6+
import lombok.NoArgsConstructor;
47

58
import java.io.Serializable;
69

710
/**
811
* jspai signature.
12+
*
13+
* @author chanjarster
914
*/
1015
@Data
16+
@Builder
17+
@NoArgsConstructor
18+
@AllArgsConstructor
1119
public class WxJsapiSignature implements Serializable {
1220
private static final long serialVersionUID = -1116808193154384804L;
1321

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cn.binarywang.wx.miniapp.api;
2+
3+
import me.chanjar.weixin.common.bean.WxJsapiSignature;
4+
import me.chanjar.weixin.common.error.WxErrorException;
5+
6+
/**
7+
* <pre>
8+
* jsapi相关接口
9+
* Created by BinaryWang on 2018/8/5.
10+
* </pre>
11+
*
12+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
13+
*/
14+
public interface WxMaJsapiService {
15+
/**
16+
* 获得jsapi_ticket的url
17+
*/
18+
String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
19+
20+
/**
21+
* 获得jsapi_ticket,不强制刷新jsapi_ticket
22+
*
23+
* @see #getJsapiTicket(boolean)
24+
*/
25+
String getJsapiTicket() throws WxErrorException;
26+
27+
/**
28+
* <pre>
29+
* 获得jsapi_ticket
30+
* 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
31+
*
32+
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
33+
* </pre>
34+
*
35+
* @param forceRefresh 强制刷新
36+
*/
37+
String getJsapiTicket(boolean forceRefresh) throws WxErrorException;
38+
39+
/**
40+
* <pre>
41+
* 创建调用jsapi时所需要的签名
42+
*
43+
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
44+
* </pre>
45+
*/
46+
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
47+
48+
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
44
import cn.binarywang.wx.miniapp.config.WxMaConfig;
5+
import me.chanjar.weixin.common.bean.WxJsapiSignature;
56
import me.chanjar.weixin.common.error.WxErrorException;
67
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
78
import me.chanjar.weixin.common.util.http.RequestExecutor;
@@ -17,6 +18,7 @@ public interface WxMaService {
1718
String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
1819

1920
String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
21+
2022
/**
2123
* 获取登录后的session信息
2224
*
@@ -149,6 +151,13 @@ public interface WxMaService {
149151
*/
150152
WxMaCodeService getCodeService();
151153

154+
/**
155+
* 返回jsapi操作相关的 API服务类对象
156+
*
157+
* @return WxMaJsapiService
158+
*/
159+
WxMaJsapiService getJsapiService();
160+
152161
/**
153162
* 小程序修改服务器地址、成员管理 API
154163
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cn.binarywang.wx.miniapp.api.impl;
2+
3+
import cn.binarywang.wx.miniapp.api.WxMaJsapiService;
4+
import cn.binarywang.wx.miniapp.api.WxMaService;
5+
import com.google.gson.JsonElement;
6+
import com.google.gson.JsonObject;
7+
import com.google.gson.JsonParser;
8+
import me.chanjar.weixin.common.bean.WxJsapiSignature;
9+
import me.chanjar.weixin.common.error.WxErrorException;
10+
import me.chanjar.weixin.common.util.RandomUtils;
11+
import me.chanjar.weixin.common.util.crypto.SHA1;
12+
13+
import java.util.concurrent.locks.Lock;
14+
15+
/**
16+
* <pre>
17+
* Created by BinaryWang on 2018/8/5.
18+
* </pre>
19+
*
20+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
21+
*/
22+
public class WxMaJsapiServiceImpl implements WxMaJsapiService {
23+
private static final JsonParser JSON_PARSER = new JsonParser();
24+
25+
private WxMaService wxMaService;
26+
27+
public WxMaJsapiServiceImpl(WxMaService wxMaService) {
28+
this.wxMaService = wxMaService;
29+
}
30+
31+
@Override
32+
public String getJsapiTicket() throws WxErrorException {
33+
return getJsapiTicket(false);
34+
}
35+
36+
@Override
37+
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
38+
Lock lock = this.wxMaService.getWxMaConfig().getJsapiTicketLock();
39+
try {
40+
lock.lock();
41+
if (forceRefresh) {
42+
this.wxMaService.getWxMaConfig().expireJsapiTicket();
43+
}
44+
45+
if (this.wxMaService.getWxMaConfig().isJsapiTicketExpired()) {
46+
String responseContent = this.wxMaService.get(GET_JSAPI_TICKET_URL, null);
47+
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
48+
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
49+
String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
50+
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
51+
this.wxMaService.getWxMaConfig().updateJsapiTicket(jsapiTicket, expiresInSeconds);
52+
}
53+
} finally {
54+
lock.unlock();
55+
}
56+
return this.wxMaService.getWxMaConfig().getJsapiTicket();
57+
}
58+
59+
@Override
60+
public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException {
61+
long timestamp = System.currentTimeMillis() / 1000;
62+
String randomStr = RandomUtils.getRandomStr();
63+
String jsapiTicket = getJsapiTicket(false);
64+
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
65+
"noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url);
66+
return WxJsapiSignature
67+
.builder()
68+
.appId(this.wxMaService.getWxMaConfig().getAppid())
69+
.timestamp(timestamp)
70+
.nonceStr(randomStr)
71+
.url(url)
72+
.signature(signature)
73+
.build();
74+
}
75+
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
package cn.binarywang.wx.miniapp.api.impl;
22

3-
import cn.binarywang.wx.miniapp.api.WxMaAnalysisService;
4-
import cn.binarywang.wx.miniapp.api.WxMaCodeService;
5-
import cn.binarywang.wx.miniapp.api.WxMaMediaService;
6-
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
7-
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
8-
import cn.binarywang.wx.miniapp.api.WxMaService;
9-
import cn.binarywang.wx.miniapp.api.WxMaSettingService;
10-
import cn.binarywang.wx.miniapp.api.WxMaTemplateService;
11-
import cn.binarywang.wx.miniapp.api.WxMaUserService;
3+
import cn.binarywang.wx.miniapp.api.*;
124
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
135
import cn.binarywang.wx.miniapp.config.WxMaConfig;
146
import com.google.common.base.Joiner;
@@ -58,6 +50,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
5850
private WxMaAnalysisService analysisService = new WxMaAnalysisServiceImpl(this);
5951
private WxMaCodeService codeService = new WxMaCodeServiceImpl(this);
6052
private WxMaSettingService settingService = new WxMaSettingServiceImpl(this);
53+
private WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this);
6154

6255
private int retrySleepMillis = 1000;
6356
private int maxRetryTimes = 5;
@@ -310,6 +303,11 @@ public WxMaCodeService getCodeService() {
310303
return this.codeService;
311304
}
312305

306+
@Override
307+
public WxMaJsapiService getJsapiService() {
308+
return this.jsapiService;
309+
}
310+
313311
@Override
314312
public WxMaSettingService getSettingService() {
315313
return this.settingService;

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java

+19
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@ public interface WxMaConfig {
3838
*/
3939
void updateAccessToken(String accessToken, int expiresInSeconds);
4040

41+
String getJsapiTicket();
42+
43+
Lock getJsapiTicketLock();
44+
45+
boolean isJsapiTicketExpired();
46+
47+
/**
48+
* 强制将jsapi ticket过期掉
49+
*/
50+
void expireJsapiTicket();
51+
52+
/**
53+
* 应该是线程安全的
54+
*
55+
* @param jsapiTicket 新的jsapi ticket值
56+
* @param expiresInSeconds 过期时间,以秒为单位
57+
*/
58+
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
59+
4160
String getAppid();
4261

4362
String getSecret();

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java

+31
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ public class WxMaInMemoryConfig implements WxMaConfig {
2727
protected volatile String httpProxyUsername;
2828
protected volatile String httpProxyPassword;
2929

30+
protected volatile String jsapiTicket;
31+
protected volatile long jsapiTicketExpiresTime;
32+
3033
protected Lock accessTokenLock = new ReentrantLock();
34+
protected Lock jsapiTicketLock = new ReentrantLock();
3135

3236
/**
3337
* 临时文件目录
@@ -70,6 +74,33 @@ public synchronized void updateAccessToken(String accessToken, int expiresInSeco
7074
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
7175
}
7276

77+
@Override
78+
public String getJsapiTicket() {
79+
return this.jsapiTicket;
80+
}
81+
82+
@Override
83+
public Lock getJsapiTicketLock() {
84+
return this.jsapiTicketLock;
85+
}
86+
87+
@Override
88+
public boolean isJsapiTicketExpired() {
89+
return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
90+
}
91+
92+
@Override
93+
public void expireJsapiTicket() {
94+
this.jsapiTicketExpiresTime = 0;
95+
}
96+
97+
@Override
98+
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
99+
this.jsapiTicket = jsapiTicket;
100+
// 预留200秒的时间
101+
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
102+
}
103+
73104
@Override
74105
public void expireAccessToken() {
75106
this.expiresTime = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package cn.binarywang.wx.miniapp.api.impl;
2+
3+
import cn.binarywang.wx.miniapp.api.WxMaService;
4+
import cn.binarywang.wx.miniapp.config.WxMaConfig;
5+
import cn.binarywang.wx.miniapp.test.ApiTestModule;
6+
import com.google.inject.Inject;
7+
import me.chanjar.weixin.common.bean.WxJsapiSignature;
8+
import me.chanjar.weixin.common.error.WxErrorException;
9+
import org.testng.annotations.Guice;
10+
import org.testng.annotations.Test;
11+
12+
import static org.assertj.core.api.Assertions.assertThat;
13+
14+
/**
15+
* <pre>
16+
* Created by BinaryWang on 2018/8/5.
17+
* </pre>
18+
*
19+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
20+
*/
21+
@Test
22+
@Guice(modules = ApiTestModule.class)
23+
public class WxMaJsapiServiceImplTest {
24+
@Inject
25+
private WxMaService wxService;
26+
@Inject
27+
private WxMaConfig wxMaConfig;
28+
29+
@Test
30+
public void testGetJsapiTicket() throws WxErrorException {
31+
assertThat(this.wxService.getJsapiService().getJsapiTicket()).isNotBlank();
32+
}
33+
34+
@Test
35+
public void testGetJsapiTicket1() throws WxErrorException {
36+
assertThat(this.wxService.getJsapiService().getJsapiTicket(true)).isNotBlank();
37+
}
38+
39+
@Test
40+
public void testCreateJsapiSignature() throws WxErrorException {
41+
final WxJsapiSignature jsapiSignature = this.wxService.getJsapiService().createJsapiSignature("http://www.qq.com");
42+
System.out.println(jsapiSignature);
43+
assertThat(jsapiSignature).isNotNull();
44+
}
45+
}

weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public void setTemplateId(String templateId) {
5454
this.templateId = templateId;
5555
}
5656

57+
@Override
5758
public void setAccessTokenLock(Lock lock) {
5859
super.accessTokenLock = lock;
5960
}

0 commit comments

Comments
 (0)