最近在做小程序,有个需求是生成小程序的二维码,扫二维码,进入到小程序指定页面。
1、获取token
获取小程序二维码之前,首先需要获取access_token。access_token是有时效性的2小时,每获取一次上次的的access_token就会失效。我们把请求到的access_token放到redis,失效时间设置为2小时,每次请求token,先从redis取,取不到则请求微信获取access_token。
@Autowired
private StringRedisTemplate stringRedisTemplate;
public String getToken(String appId,String secret) {
Token instanceToken = getAccessToken(appId);
return instanceToken == null ? "" : instanceToken.getAccess_token();
}
public Token getAccessToken(String appid) {
Token instanceToken = null;
try {
String tokenJson = stringRedisTemplate.get(ConstantRedis.REDIS_KEY.WECHAT_ACCESS_TOKEN.generateFullKey(appid));
if (!StringUtils.isEmpty(tokenJson)) {
instanceToken = JSON.parseObject(tokenJson, Token.class);
}
if (instanceToken == null || StringUtils.isEmpty(instanceToken.getAccess_token()) || instanceToken.isExpire()) {
instanceToken = WechatAPI.getToken(appid,secret);
if (instanceToken == null || StringUtils.isEmpty(instanceToken.getAccess_token())) {
return null;
}
stringRedisTemplate.set(ConstantRedis.REDIS_KEY.WECHAT_ACCESS_TOKEN.generateFullKey(appid), instanceToken, 7200L);
}
} catch (IOException ex) {
logger.error("getAccessToken exception...{}", ex);
}
return instanceToken;
}
public class WechatAPI {
privite static final String WECHAT_URI = "https://api.weixin.qq.com";
/**
* 调用微信SDK请求获取access_token
* @param appid
* @param secret
* @return
*/
public static Token getToken(String appid, String secret) {
HttpUriRequest httpUriRequest = RequestBuilder.get()
.setUri(WECHAT_URI + "/cgi-bin/token")
.addParameter("grant_type", "client_credential")
.addParameter("appid", appid)
.addParameter("secret", secret)
.build();
Token token = MyHttpClient.executeJsonResult(httpUriRequest, Token.class);
token.setCreate_time_millis(System.currentTimeMillis());
return token;
}
}
package com.wechat.client;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class MyHttpClient {
private static final int maxTotal = 100;
private static final int maxPerRouter = 10;
private static final int timeout = 6000;
private static final int retryExecutionCount = 1;
private static final Logger logger = LoggerFactory.getLogger(MyHttpClient.class);
protected static CloseableHttpClient httpClient = HttpClientFactory.createHttpClient(maxTotal, maxPerRouter, timeout, retryExecutionCount);
public static void init(int maxTotal, int maxPerRoute) {
try {
httpClient.close();
httpClient = HttpClientFactory.createHttpClient(maxTotal, maxPerRoute, timeout, retryExecutionCount);
} catch (IOException e) {
logger.error("init exception...", e);
}
}
public static CloseableHttpResponse execute(HttpUriRequest request) {
try {
return httpClient.execute(request, HttpClientContext.create());
} catch (Exception e) {
e.printStackTrace();
logger.error("CloseableHttpResponse exception...", e);
}
return null;
}
public static <T> T execute(HttpUriRequest request, ResponseHandler<T> responseHandler) {
try {
T t = httpClient.execute(request, responseHandler, HttpClientContext.create());
return t;
} catch (Exception e) {
e.printStackTrace();
logger.error("execute exception...", e);
}
return null;
}
public static <T> T executeJsonResult(HttpUriRequest request, Class<T> clazz) {
return execute(request, JsonResponseHandler.createResponseHandler(clazz));
}
}
public class Token implements Serializable {
private String access_token;
private long expires_in;
private long create_time_millis;
private static final long MILLIS = 1000L;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public long getExpires_in() {
return expires_in;
}
public void setExpires_in(long expires_in) {
this.expires_in = expires_in;
}
public long getCreate_time_millis() {
return create_time_millis;
}
public void setCreate_time_millis(long create_time_millis) {
this.create_time_millis = create_time_millis;
}
}
2、有了access_token我们就可以请求微信SDK获取二维码了。
public String getQrcode(QrcodeReq qrcodeReq) {
InputStream inputStream = null;
String fileName = "";
String key = "qrcode"+qrcodeReq.getVideoId();
try {
String token = getToken(qrcodeReq.getAppId());
logger.info("getQrcode token:{}", token);
fileName= "qrcode/qrcode"+qrcodeReq.getVideoId()+".png";
RestTemplate rest = new RestTemplate();
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;
Map<String, Object> param = new HashMap<>();
param.put("scene", "xxxxxxxxx");
param.put("page", "pages/play/play");
param.put("width", qrcodeReq.getWidth());
param.put("auto_color", false);
Map<String, Object> line_color = new HashMap<>();
line_color.put("r", 0);
line_color.put("g", 0);
line_color.put("b", 0);
param.put("line_color", line_color);
logger.info("调用生成微信URL接口传参:" + param);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/json");
HttpEntity requestEntity = new HttpEntity(JSON.toJSON(param), headers);
ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
byte[] result = entity.getBody();
String re = JsonUtil.decodeBase64(JSON.toJSONString(entity.getBody()));
if (entity.getBody() !=null && !re.contains("errcode")){
inputStream = new ByteArrayInputStream(result);
String str = uploadService.putObject(fileName, inputStream);
}else {
logger.info("调用小程序生成微信永久小程序码URL接口返回结果:" + re);
}
}catch (Exception e){
logger.error("getQrcode:{}",e);
}finally {
if (inputStream !=null){
try {
inputStream.close();
} catch (IOException e) {
logger.error("getQrcode:{}",e);
}
}
}
return fileName;
}
3、上传oss
public String putObject(String filename,InputStream inputStream) {
// 上传Object.
PutObjectResult result = null;
try {
result = client.putObject(defaultBucket, filename, inputStream);
} catch (OSSException e) {
logger.info("putObject putObject to oss error:{}",e);
} catch (ClientException e) {
logger.info("putObject putObject to oss error:{}",e);
}
String path = result.getETag();
if (StringUtils.isEmpty(path)){
return "";
}else {
return path;
}
}
4、有了二维码。总得测试一下,不然我好慌。
在微信开发这工具编译的左边的下拉框,是可以自定义编译的,启动页面和启动参数分别是请求生成二维码的page、scene。
小程序页面 js
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 扫二维码
if (options.scene) {
let scene = decodeURIComponent(options.scene);
//
}else{
}
好了,获取小程序二维码就简单介绍到这了,有问题请留言吧 (^v^)