对于微信公众号的开发来说,
access_token是一个很重要的标识,
调用公众号接口都需要带上这个标识
微信接口说明:
里面提到的appid和secret就是公众号的基本配置
微信公众号→开发→基本配置
我这里用到的是springBoot框架,然后拿着微信提供的访问链接,替换参数调用
@Value("${wx.access_token_url}")
private String accessTokenUrl;
@Value("${wx.appId}")
private String appId;
@Value("${wx.secret}")
private String secret;
@Override
public String getWeChatAccessTokenUrl() {
try {
String url = accessTokenUrl.replace("APPID",appId).replace("APPSECRET",secret);
logger.info("请求获取access_token的url:" + url);
return RestTemplateUtil.get(url);
} catch (Exception e) {
e.printStackTrace();
return "请求获取access_token出现异常";
}
}
用到的参数我已经放到配置文件里面去了,用@value来获取,然后把公众号的参数替换进微信提供的url里面去。
下面我会把代码,以及工具类贴出来,写完代码并不是直接可以调用的,还有一件事情要做。
如果写完之后直接调用,微信端会给你返回错误码
意思就是你访问微信的ip并不在白名单内,需要去微信公众号配置
微信公众号→开发→基本配置→IP白名单
把你访问的ip配置上,就可以获取access_token了
还需要注意的是access_token是有时间限制的,每次获取可以用两个小时,多个业务调用也会影响access_token的唯一性,微信每天获取access_token的次数也有限制...balabala一堆东西
可以写一个定时任务,
access_token虽然时效是两小时,但是定时任务可以半个小时或者一个小时调用一次,毕竟每天可以调用2000次(小声比比)
千万不要两个小时调用一次,很可能会出现时间差问题,导致access_token失效
取到的access_token存进数据库中,最好存进redis里面,redis里面找不到再去数据库查询,供多个业务使用。这样可以避免多个业务调用,后一个access_token导致前一个access_token失效等乱七八糟的问题
一些具体细节,返回状态码,可以去微信文档查看
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
现在开始放代码...
controller类
package com.cy.one.controller;
import com.cy.one.service.WeChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 微信业务接口类
* @author cy
*/
@RestController
@RequestMapping("v1/weChat")
public class WeChatController {
@Autowired
private WeChatService weChatService;
/**
* 获取微信access_token
* @return
*/
@GetMapping("getWeChatAccessTokenUrl")
public String getWeChatAccessTokenUrl(){
return weChatService.getWeChatAccessTokenUrl();
}
}
service接口类
package com.cy.one.service;
/**
* 微信业务 业务接口类
* @author cy
*/
public interface WeChatService {
/**
* 获取微信access_token
* @return
*/
public String getWeChatAccessTokenUrl();
}
service实现类
package com.cy.one.service.impl;
import com.cy.one.service.WeChatService;
import com.cy.one.utils.RestTemplateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* 微信业务 业务实现类
* @author cy
*/
@Service
public class WeChatServiceImpl implements WeChatService {
Logger logger = LoggerFactory.getLogger(WeChatServiceImpl.class);
@Value("${wx.access_token_url}")
private String accessTokenUrl;
@Value("${wx.appId}")
private String appId;
@Value("${wx.secret}")
private String secret;
@Override
public String getWeChatAccessTokenUrl() {
try {
String url = accessTokenUrl.replace("APPID",appId).replace("APPSECRET",secret);
logger.info("请求获取access_token的url:" + url);
return RestTemplateUtil.get(url);
} catch (Exception e) {
e.printStackTrace();
return "请求获取access_token出现异常";
}
}
}
配置文件.yml
wx:
access_token_url: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
appId: 替换自己微信公众号的appId
secret: 替换自己微信公众号的secret
工具类
package com.cy.one.utils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
/**
* ClassName: RestTemplateUtil
*
* @Description: http请求传输类
* @author cy
*/
@Component
public class RestTemplateUtil {
private static class SingleTonHolder{
private static RestTemplate restTemplate = new RestTemplate();
}
private RestTemplateUtil() {}
/**
* 单例实例
* @return
*/
public static RestTemplate getInstance(){
return SingleTonHolder.restTemplate;
}
/**
* post请求 不加密
* @param requestUrl 访问连接
* @param data 传输参数json
* @return
*/
public static String post(String requestUrl, String data ){
try {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Content-Type","application/json; charset=utf-8");
HttpEntity<String> httpEntity = new HttpEntity<>(data, httpHeaders);
return RestTemplateUtil.getInstance().postForObject(requestUrl,httpEntity,String.class);
} catch (Exception e) {
e.printStackTrace();
return "请求失败";
}
}
/**
* get根据url获取对象
*/
public static String get(String url) {
try {
return RestTemplateUtil.getInstance().getForObject(url, String.class, new Object[] {});
} catch (RestClientException e) {
e.printStackTrace();
return "请求失败";
}
}
}