微信公眾號開發之Access token+redis存儲token(三)


自定義菜單需要獲取Access token

公眾號使用AppID和AppSecret調用接口來獲取access_token
公眾號和小程序均可以使用AppID和AppSecret調用本接口來獲取access_token。AppID和AppSecret可在“微信公眾平台-開發-基本配置”頁中獲得

access_token是公眾號的全局唯一接口調用憑據,公眾號調用各接口時都需使用access_token。開發者需要進行妥善保存。access_token的存儲至少要保留512個字符空間。access_token的有效期目前為2個小時,需定時刷新,重復獲取將導致上次獲取的access_token失效。

access_token的有效期是7200秒(兩小時),在有效期內,可以一直使用,只有當access_token過期時,才需要再次調用接口 獲取access_token。在理想情況下,一個7x24小時運行的系統,每天只需要獲取12次access_token,即每2小時獲取一次。如果在 有效期內,再次獲取access_token,那么上一次獲取的access_token將失效。
目前,獲取access_token接口的調用頻率限制為2000次/天,如果每次發送客服消息、獲取用戶信息、群發消息之前都要先調用獲取 access_token接口得到接口訪問憑證,這顯然是不合理的,一方面會更耗時(多了一次接口調用操作),另一方面2000次/天的調用限制恐怕也不 夠用。因此,在實際應用中,我們需要將獲取到的access_token存儲起來,然后定期調用access_token接口更新它,以保證隨時取出的 access_token都是有效的。

原文鏈接

先看完成的例子

接口調用請求說明

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

參數說明

參數 說明
grant_type 獲取access_token填寫client_credential
appid 第三方用戶唯一憑證
secret 第三方用戶唯一憑證密鑰,即appsecret

返回說明

正常情況下,微信會返回下述JSON數據包給公眾號:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
參數說明

參數 說明
access_token 獲取到的憑證
expires_in 憑證有效時間,單位:秒

封裝這兩個參數

package com.rzk.pojo;

import lombok.Data;

@Data
public class Token {
    private String accessToken;
    private int expiresIn;
}

HttpConstant

package com.rzk.util;
public class HttpConstant {

    //獲取Access token URI
    public static String API_URI = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
}

HttpClient 工具類

package com.rzk.util;

import com.rzk.pojo.Token;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpClient {

    /**
     * GET請求
     * @param url
     * @return
     */
    public static String doGetRequest(String url) {
        String result = "";
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity responseEntity = response.getEntity();
            result = EntityUtils.toString(responseEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }  finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }return result;
    }
}

WxServerController

    @GetMapping(value = "accessToken")
    public String AccessToken(){
        Token token = new Token();
        //使用httpclient請求
        String result = HttpClient.doGetRequest(HttpConstant.API_URI.replace("APPID", environment.getProperty("wx.appid")).replace("APPSECRET", environment.getProperty("wx.secret")));
        //轉成json對象
        JSONObject json = JSON.parseObject(result);
        token.setAccessToken(String.valueOf(json.get("access_token")));

        return token.getAccessToken();
    }

請求accessToken

還要去公眾號基礎設置開啟白名單訪問列表,填上你的服務器ip地址即可

整合redis存儲accessToken

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.rzk</groupId>
    <artifactId>wxserver</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>wxserver</name>
    <description>wxserver</description>
    <properties>
        <java.version>1.8</java.version>
        <httpclient.version>4.5.13</httpclient.version>
        <fastjson.version>1.2.76</fastjson.version>
        <commons-lang.version>2.6</commons-lang.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>${commons-lang.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

application.yml配置文件

配置文件


spring:
  redis:
    #超過時間
    timeout: 10000ms
    #地址
    host: ip
    #端口
    port: 6382
    #數據庫
    database: 0
    password: 密碼
    lettuce:
      pool:
        #最大連接數 默認8
        max-active: 1024
        # 最大連接阻塞等待時間,默認-1
        max-wait: 10000ms
        #最大空閑連接
        max-idle: 200
        #最小空閑連接
        min-idle: 5
    #哨兵模式
    sentinel:
      #主節點名稱
      master: mymaster
      #節點
      nodes: ip:26381,ip:26382,ip:26383

Controller


    @GetMapping(value = "accessToken")
    public String getAccessToken(){
        Token token = new Token();
        //如果不等於空 或者小於600秒
        if (redisTemplate.getExpire("expires_in")<600||redisTemplate.getExpire("expires_in")==null){

            //使用httpclient請求
            String result = HttpClient.doGetRequest(HttpConstant.API_URI.replace("APPID", environment.getProperty("wx.appid")).replace("APPSECRET", environment.getProperty("wx.secret")));

            //轉成json對象
            JSONObject json = JSON.parseObject(result);
            System.out.println(json);
            token.setAccessToken(String.valueOf(json.get("access_token")));
            token.setExpiresIn((Integer) json.get("expires_in"));
            System.out.println(json.get("expires_in"));
            System.out.println(token.getExpiresIn());
            redisTemplate.opsForValue().set("accessToken",json.get("access_token"));
            redisTemplate.opsForValue().set("expiresIn",json.get("expires_in"),7200, TimeUnit.SECONDS);
        }
        String accessToken = redisTemplate.opsForValue().get("accessToken").toString();
        Long expiresIn = redisTemplate.getExpire("expiresIn");
        logger.info("accessToken{}:"+accessToken);
        logger.info("expiresIn{}:"+expiresIn);

        return token.getAccessToken();
    }

我使用redis流程

后續可用springboot自帶的定時任務處理器去開啟定時任務功能
這里就不貼定時任務的代碼了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM