JAVA后端通过微信getAccessToken接口获取access_token

项目场景:

项目是微信小程序端,需要实现快捷登录功能,所以需要定时调用getAccessToken接口获取微信的access_token并存入redis,以供后续接口查询。

微信开发文档链接:微信getAccessToken开发文档

调用详情:

接口的调用地址:

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

其中需要传入三个参数:
grant_type:直接填写String类型的 client_credential
appid :小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态)
secret :小程序唯一凭证密钥,即 AppSecret,获取方式同 appid

具体业务代码

 	private final static String ACCESS_TOKEN_KEY = "accessToken";

    Logger logger = LoggerFactory.getLogger(WxLonginServiceImpl.class);

    @Resource
    RedisUtil redisUtil;
    @ApiModelProperty("小程序 appId")
    @Value("${wx.appid}")
    private String appid;

    @ApiModelProperty("小程序 appSecret")
    @Value("${wx.secret}")
    private String secret;

    @ApiModelProperty("授权类型,此处只需填写 authorization_code")
    @Value("${wx.grant_type}")
    private String grant_type;
    /**
     * 获取微信token
     * @return
     */
    @Override
    public WxAccessToken getAccessToken() {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
        String loginJson = null;
        try {
            loginJson = HttpUtils.doGet(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JsonUtils.parse(loginJson, WxAccessToken.class);
    }

/**
     *  微信accessToken接口得到的accessToken可以保存2小时,为了
     *  设置定时,将定时设置为 1小时55分钟 ~ 2小时之内
     *  access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效;
     *  建议开发者使用中控服务器统一获取和刷新 access_token,其他业务逻辑服务器所使用的 access_token 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致 access_token 覆盖而影响业务;
     *  access_token 的有效期通过返回的 expires_in 来传达,目前是7200秒之内的值,中控服务器需要根据这个有效时间提前去刷新。在刷新过程中,中控服务器可对外继续输出的老 access_token,此时公众平台后台会保证在5分钟内,新老 access_token 都可用,这保证了第三方业务的平滑过渡;
     *  access_token 的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新 access_token 的接口,这样便于业务服务器在API调用获知 access_token 已超时的情况下,可以触发 access_token 的刷新流程。
     */
    @Scheduled(fixedDelay = 7080000)
    @Override
    public void addAccessToken() {
        String accessToken = getAccessToken().getAccess_token();
        logger.info("定时任务启用===========" + accessToken);
        //微信token2小时过期,每小时重新获得一次,
        redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, 7200, TimeUnit.SECONDS);
    }

启动类代码:

/**
 * @Author: 
 * @Description: 启动类
 * @Date: create in 2020/12/3 9:00
 */

@EnableTransactionManagement
@SpringBootApplication
@EnableScheduling
@EnableSwagger2
@MapperScan("com.test.back.mapper")
public class SpringBootMain {


    public static void main(String[] args) {
        SpringApplication.run(SpringBootMain.class, args);
    }

    /**
     * 解决获取request 空指针的问题
     * @return
     */
    @Bean
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }

}  

实体类

/**
 * @Author: 
 * @Description: 微信小程序获取
 * @Date: create in 2021/1/5 9:18
 */
@Configuration
@Data
public class WxAccessToken {

    @ApiModelProperty("获取到的凭证")
    private String access_token;

    @ApiModelProperty("凭证有效时间,单位:秒。目前是7200秒之内的值。")
    private String expires_in;

    @ApiModelProperty("错误码")
    private String errcode;

    @ApiModelProperty("错误信息")
    private String errmsg;


}

总结

为了项目的可维护性,我将使用的appid,secret,grant_type这三个参数配置在yml里面,方便修改,不喜欢可以自行设置在类中定时任务使用。有疑问可以提出。

2022-1-7日添加HttpUtils工具类


import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpUtils {
    public static String doGet(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doGet(String url) {
        return doGet(url, null);
    }

    public static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doPost(String url) {
        return doPost(url, null);
    }

    /**
     * 请求的参数类型为json
     * @param url
     * @param json
     * @return
     * {username:"",pass:""}
     */
    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值