上节写了配置地址到微信公众平台,这次写获取AccessToken
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
由接口文档可以看出获取Access token 需要GET请求并上送grant_type、appid、secret。
其中grant_type 上送默认值: client_credential
而appid、secret在公众平台首页
可以先通过微信公众平台接口调试工具进行调试,可以看到返回access_token(获取到的凭证)、以及expires_in (凭证有效时间,单位:秒)
创建 AccessTokenBean 对象
import lombok.Getter;
import java.io.Serializable;
import java.util.HashMap;
/**
* @Author : lizzu
* @create 2022/9/24 21:35
* access token 对象
*/
@Getter
public class AccessTokenBean implements Serializable {
/**
* grant_type 固定值,直接填写client_credential
*/
private String grant_type = "client_credential";
/**
* appID 用户的唯一标识
*/
private String appid;
/**
* secret 用户唯一凭证密钥
*/
private String secret;
/**
* 获取到的access token
*/
private String accessToken;
/**
* access token 过期时间
*/
private long expiresTime;
private AccessTokenBean(String appid, String secret, String accessToken, long expiresTime) {
this.appid = appid;
this.secret = secret;
this.accessToken = accessToken;
//失效时间 返回单位:秒
//判断失效处理时方便判断
if (expiresTime>0){
this.expiresTime = System.currentTimeMillis()+expiresTime*1000;
}
}
/**
* 构建获取access token 请求对象
*
* @param appId 用户唯一标识
* @param secret 用户唯一标识密钥
* @return {@link HashMap}
*/
public static HashMap<String, String> requestOf(String appId, String secret) {
HashMap<String, String> requestMap =new HashMap<>(16);//16为默认初始值
requestMap.put("appid",appId);
requestMap.put("secret",secret);
requestMap.put("grant_type", "client_credential");
return requestMap;
}
/**
* 构建AccessToken 对象
*
* @param accessToken token
* @param expiresTime 过期时间
* @return {@link AccessTokenBean}
*/
public static AccessTokenBean responseOf(String accessToken, long expiresTime) {
return new AccessTokenBean("", "", accessToken, expiresTime);
}
/**
* 判断token是否已经失效
*
* @return 是否失效 false 未失效 true 失效,需要重新申请
*/
public boolean isExpired() {
return System.currentTimeMillis() > expiresTime;
}
}
将appid、secret参数放到配置类中 WeCharConfig
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Author : lizzu
* @create 2022/9/24 21:37
*/
@Component
@Data
@ConfigurationProperties(prefix = "we-char")
public class WeCharConfig {
/**
* 用户唯一标识
*/
private String appId;
/**
* 用户密钥
*/
private String secret;
/**
* 加密token
*/
private String token;
}
配置文件application.yml
application:
name: my-spring-wechar
server:
port: 8085
we-char:
app-id: 你的app-id
secret: 你的secret
token: 你的token
访问路径实体类WeCharConstant
···
/**
-
@Author : lizzu
-
@create 2022/9/25 15:15
*/
public class WeCharConstant {/**
- 获取Token
*/
public static final String GET_TOKEN_URL = “https://api.weixin.qq.com/cgi-bin/token”;
- 获取Token
}
···
AccessTokenService,在获取方法中判断accessTokenBean 是否已经生成或已过期。当未生成或已过期时调用重新生成Token方法
import cn.org.spring.common.util.HttpClientUtils;
import com.alibaba.fastjson.JSONObject;
import com.ctsi.sddx.bean.AccessTokenBean;
import com.ctsi.sddx.config.WeCharConfig;
import com.ctsi.sddx.constants.WeCharConstant;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
/**
* @Author : lizzu
* @create 2022/9/24 21:51
*/
@Service
public class AccessTokenService {
@Resource
WeCharConfig weCharConfig;
/**
* access token 对象
*/
private AccessTokenBean accessTokenBean;
private static final String URL = WeCharConstant.GET_TOKEN_URL;
/**
* 获取access token
*
* @param appId
* @param appSecret
*/
private void refreshAccessToken(String appId, String appSecret) throws IOException {
String s = HttpClientUtils.get(URL, AccessTokenBean.requestOf(appId, appSecret));
JSONObject jsonObject = JSONObject.parseObject(s);
long expiresIn = jsonObject.getLong("expires_in");
String accessToken = jsonObject.getString("access_token");
accessTokenBean = AccessTokenBean.responseOf(accessToken, expiresIn);
}
/**
* 获取access token
*
* @return
*/
public String getAccessToken() throws IOException {
if (accessTokenBean==null||accessTokenBean.isExpired()){
refreshAccessToken(weCharConfig.getAppId(), weCharConfig.getSecret());
}
return accessTokenBean.getAccessToken();
}
}
WeCharController 测试
import cn.org.spring.common.util.XmlUtils;
import com.ctsi.sddx.bean.message.TextMessage;
import com.ctsi.sddx.service.AccessTokenService;
import com.ctsi.sddx.utils.AccessAuthentication;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
/**
* @Author : lizzu
* @create 2022/9/24 20:26
*/
@RestController
@RequestMapping("/v1/weChart")
public class WeCharController {
private String token = "lizzuabc123123";
@Resource
AccessTokenService accessTokenService;
//接口测试
@PostMapping("/info")
public String getInfo(){
return "hello word ! ";
}
@GetMapping
public String getWeChar(@RequestParam String signature,
@RequestParam String timestamp,
@RequestParam String nonce,
@RequestParam String echostr) {
System.out.println("signature :" + signature);
System.out.println("timestamp :" + timestamp);
System.out.println("nonce :" + nonce);
System.out.println("echostr :" + echostr);
if (AccessAuthentication.of(token, timestamp, nonce, signature).checkSignature()) {
return echostr;
}
return null;
}
@GetMapping("/getAccessToken")
public String getAccessToken () throws IOException {
String accessToken = accessTokenService.getAccessToken();
return accessToken;
}
到此获取Access token完成
下一篇: 自定义菜单