博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
手写一个生成带参数 微信二维码的工具类
阅读量:3950 次
发布时间:2019-05-24

本文共 8221 字,大约阅读时间需要 27 分钟。

1.先定义接口

package com.example.mongodemo.framework.wechat;import com.example.mongodemo.framework.wechat.entity.AccessToken;import com.example.mongodemo.framework.wechat.entity.ImageTicket;import com.example.mongodemo.framework.wechat.entity.LoginUser;import org.checkerframework.checker.signature.qual.FieldDescriptorForPrimitive;/** * @Author lyr * @create 2020/4/19 15:54 */public interface WechatTemplate {
/** * 获取token的 url,没什么用 * @return 生成获取 token的 url */ @Deprecated String generateTokenUrl(); /** * 请求微信接口,获取 accessToken * @return 返回微信的 ACCESS_TOKEN */ AccessToken getAccessTokenObject(); /** * 查看用户的登录状态 * @param sceneId 场景id * @return 返回登录状态的包装类 */ LoginUser isUserLogin(String sceneId); /** * 查看用户是否登录,后台确认登录了,返回true,否则返回 false * @param sceneId 用户场景id * @return */ boolean userIsLogin(String sceneId); /** * 设置用户已经登录 * @param sceneId 用户场景id => 表示唯一的用户 */ void setUserIsLogin(String sceneId); /** * 获取扫描二维码的图片门票 * @return 获取扫码二维码的图片门票 */ ImageTicket getImageTicket(); /** * 生成访问二维码的 url * @param ticket 门票对象 * @return */ String generateQrCodeUrl(ImageTicket ticket);}

下面是 AccesToken 的 pojo 等等

package com.example.mongodemo.framework.wechat.entity;import com.fasterxml.jackson.annotation.JsonProperty;import lombok.Data;/** * @Author lyr * @create 2020/4/19 13:50 */@Datapublic class AccessToken {
/** * redis前缀 */ public static final String REDIS_KEY = "ac_tk::actk"; @JsonProperty("access_token") private String accessTokenContent; @JsonProperty("expires_in") private Long expiresIn;}

// 生成二维码的门票

package com.example.mongodemo.framework.wechat.entity;import com.fasterxml.jackson.annotation.JsonProperty;import lombok.Data;import lombok.experimental.Accessors;/** * @Author lyr * @create 2020/4/19 16:00 * 获取微信二维码的门票 * */@Data@Accessors(chain = true)public class ImageTicket {
/** * 获取微信二维码门票的链接 */ public static final String GET_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?" + "access_token=" + "%s"; /** * 获取微信二维码的门票 */ @JsonProperty("ticket") private String ticket; /** * 过期时间 */ @JsonProperty("expires_seconds") private Integer expireSeconds; /** * 返回给前端,让前端用这个 sceneId 轮询后端接口,确认是否用户已经登录 */ private String sceneId;}

用户登录状态实体(这里其实不用看的,你要什么业务,定义什么接口)

package com.example.mongodemo.framework.wechat.entity;import com.example.mongodemo.pojo.WeixinUserInfo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.RequiredArgsConstructor;import lombok.experimental.Accessors;/** * @Author lyr * @create 2020/4/19 15:29 */@Data@Accessors(chain = true)@AllArgsConstructorpublic class LoginUser {
public static final String REDIS_KEY= "loginuser::"; private String sceneId; /** * 登录状态 */ private Boolean loginStatus = false; public LoginUser(String sceneId) {
this.sceneId = sceneId; }}

请求接口,获取门票的配置

package com.example.mongodemo.framework.wechat.entity;import com.fasterxml.jackson.annotation.JsonProperty;import lombok.Data;import lombok.experimental.Accessors;/** * @Author lyr * @create 2020/4/19 16:20 */@Data@Accessors(chain = true)public class TicketRequest {
public static final String REQUEST_TICKET_URL ="https://api.weixin.qq.com/cgi-bin/qrcode/create?" + "access_token=" + "%s" ; public static final String REQUEST_TEMPLATE ="{\n" + " \"expire_seconds\": 1800,\n" + " \"action_name\": \"QR_SCENE\",\n" + " \"action_info\": {\n" + " \"scene\": {\n" + " \"scene_str\": \"%s\"\n" + " }\n" + " }\n" + "}";}

wechatTemplate 的实现

package com.example.mongodemo.framework.wechat;import com.example.mongodemo.framework.wechat.entity.AccessToken;import com.example.mongodemo.framework.wechat.entity.ImageTicket;import com.example.mongodemo.framework.wechat.entity.LoginUser;import com.example.mongodemo.framework.wechat.entity.TicketRequest;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Component;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;import java.time.Duration;/** * @Author lyr * @create 2020/4/19 11:31 */@Component@Slf4jpublic class RestWechatTemplate implements WechatTemplate{
/** * 获取 调用接口权限 的 ac token */ @Value("${wechatTemplate.getTicket.appid}") private String appId; /** * 密钥 */ @Value("${wechatTemplate.getTicket.secret}") private String secret; @Value("${wechatTemplate.getTicket.grant_type}") private String grantType; @Resource private RedisTemplate
redisTemplate; /** * 远程调用 微信接口 */ @Resource private RestTemplate restTemplate; /** * @return 生成请求微信接口的 url => 请求 微信token的 url */ @Override public String generateTokenUrl() {
String getBasicAccessToken = "https://api.weixin.qq.com/cgi-bin/" + "token?" + "grant_type=%s" + "&" + "appid=%s" + "&" + "secret=%s"; return String.format(getBasicAccessToken,grantType,appId,secret); // //log.info("微信返回结果 {}",responseString); // return responseString; } /** * 公众号每日 10000 次调用机会 * @return 返回 AccessToken */ @Deprecated public String getAccessToken() {
String responseString = restTemplate .getForObject(generateTokenUrl(),String.class); return responseString; } /** * @return 请求微信接口,获得 AccessToken =》将 json传转对象 */ @Override public AccessToken getAccessTokenObject() {
AccessToken token = (AccessToken) redisTemplate.opsForValue() .get(AccessToken.REDIS_KEY); if(token==null) {
//请求微信 token = restTemplate.getForObject(generateTokenUrl(),AccessToken.class); if(token!=null) {
//缓存 token 至有效时间 redisTemplate.opsForValue() .set(AccessToken.REDIS_KEY,token, Duration.ofSeconds(token.getExpiresIn()-10)); } } return token; } /** * 用户是否已经登录 * @param sceneId 场景id * @return */ @Override public LoginUser isUserLogin(String sceneId) {
LoginUser loginUser = (LoginUser) redisTemplate .opsForValue() .get(LoginUser.REDIS_KEY); return loginUser==null ? new LoginUser(sceneId):loginUser; } /** * 用户是否已经登录 * @param sceneId 场景id * @return */ @Override public boolean userIsLogin(String sceneId) {
return isUserLogin(sceneId).getLoginStatus(); } @Override public void setUserIsLogin(String sceneId) {
redisTemplate.opsForValue() .set(LoginUser.REDIS_KEY+sceneId,new LoginUser(sceneId).setLoginStatus(true)); } @Override public ImageTicket getImageTicket() {
String getTicketUrl = String .format(ImageTicket.GET_TICKET_URL, getAccessTokenObject() .getAccessTokenContent()); String sceneId = String.valueOf(System.nanoTime()); ResponseEntity
responseEntity = restTemplate .postForEntity( //url getTicketUrl, //请求参数 String.format(TicketRequest.REQUEST_TEMPLATE, sceneId), ImageTicket.class ); ImageTicket ticket = responseEntity.getBody(); return ticket!=null?ticket.setSceneId(sceneId):null; } @Override public String generateQrCodeUrl(ImageTicket ticket) {
String qrCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s"; return String.format(qrCodeUrl, ticket.getTicket()); }}

转载地址:http://hauzi.baihongyu.com/

你可能感兴趣的文章
1016 部分A+B (15 分)
查看>>
1017 A除以B (20 分)
查看>>
1019 数字黑洞 (20 分)
查看>>
1032 挖掘机技术哪家强 (20 分)
查看>>
今夕何夕 HDU - 6112 ( 模拟 )
查看>>
Dividing HDU - 1059 ( 多重背包 - 二进制简化 )
查看>>
Robberies HDU - 2955 ( 0-1背包 )
查看>>
FATE HDU - 2459 ( 二维完全背包 )
查看>>
B. Working out CodeForces - 429B (动态规划)
查看>>
10635 - Prince and Princess UVA-10635 (最长公共子序列的O(nlogn)的解法:LCS转换为LIS)
查看>>
Sizeof和Strlen
查看>>
lower_bound和upper_bound
查看>>
Subsequence POJ - 3061 ( 尺取法 )
查看>>
常见HTTP状态码大全
查看>>
Python很简单?学会魔术方法才算入门!
查看>>
大数据揭秘:低学历成功逆袭概率多少?结果令人震惊!
查看>>
这16个数据可视化案例,惊艳了全球数据行业
查看>>
大数据死亡率报告揭秘:SUV与轿车到底谁更危险?
查看>>
2017年网络流行语TOP20 , 没用过算我输!
查看>>
GitHub最著名的20个Python机器学习项目!
查看>>