mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-08-25 01:14:36 +08:00
#672 小程序增加jssdk相关接口实现
This commit is contained in:
parent
93db3237a6
commit
214e7e58fa
@ -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;
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
package cn.binarywang.wx.miniapp.api;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* jsapi相关接口
|
||||
* Created by BinaryWang on 2018/8/5.
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 获得jsapi_ticket
|
||||
* 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
|
||||
*
|
||||
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
|
||||
* </pre>
|
||||
*
|
||||
* @param forceRefresh 强制刷新
|
||||
*/
|
||||
String getJsapiTicket(boolean forceRefresh) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 创建调用jsapi时所需要的签名
|
||||
*
|
||||
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
|
||||
* </pre>
|
||||
*/
|
||||
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
|
||||
|
||||
}
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Created by BinaryWang on 2018/8/5.
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
@ -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<CloseableHttpCl
|
||||
private WxMaAnalysisService analysisService = new WxMaAnalysisServiceImpl(this);
|
||||
private WxMaCodeService codeService = new WxMaCodeServiceImpl(this);
|
||||
private WxMaSettingService settingService = new WxMaSettingServiceImpl(this);
|
||||
private WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this);
|
||||
|
||||
private int retrySleepMillis = 1000;
|
||||
private int maxRetryTimes = 5;
|
||||
@ -310,6 +303,11 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
|
||||
return this.codeService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMaJsapiService getJsapiService() {
|
||||
return this.jsapiService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMaSettingService getSettingService() {
|
||||
return this.settingService;
|
||||
|
@ -38,6 +38,25 @@ public interface WxMaConfig {
|
||||
*/
|
||||
void updateAccessToken(String accessToken, int expiresInSeconds);
|
||||
|
||||
String getJsapiTicket();
|
||||
|
||||
Lock getJsapiTicketLock();
|
||||
|
||||
boolean isJsapiTicketExpired();
|
||||
|
||||
/**
|
||||
* 强制将jsapi ticket过期掉
|
||||
*/
|
||||
void expireJsapiTicket();
|
||||
|
||||
/**
|
||||
* 应该是线程安全的
|
||||
*
|
||||
* @param jsapiTicket 新的jsapi ticket值
|
||||
* @param expiresInSeconds 过期时间,以秒为单位
|
||||
*/
|
||||
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
|
||||
|
||||
String getAppid();
|
||||
|
||||
String getSecret();
|
||||
|
@ -27,7 +27,11 @@ public class WxMaInMemoryConfig implements WxMaConfig {
|
||||
protected volatile String httpProxyUsername;
|
||||
protected volatile String httpProxyPassword;
|
||||
|
||||
protected volatile String jsapiTicket;
|
||||
protected volatile long jsapiTicketExpiresTime;
|
||||
|
||||
protected Lock accessTokenLock = new ReentrantLock();
|
||||
protected Lock jsapiTicketLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* 临时文件目录
|
||||
@ -70,6 +74,33 @@ public class WxMaInMemoryConfig implements WxMaConfig {
|
||||
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsapiTicket() {
|
||||
return this.jsapiTicket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getJsapiTicketLock() {
|
||||
return this.jsapiTicketLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJsapiTicketExpired() {
|
||||
return System.currentTimeMillis() > 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;
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Created by BinaryWang on 2018/8/5.
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@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();
|
||||
}
|
||||
}
|
@ -54,6 +54,7 @@ public class TestConfig extends WxMaInMemoryConfig {
|
||||
this.templateId = templateId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessTokenLock(Lock lock) {
|
||||
super.accessTokenLock = lock;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user