Java微信公眾號開發----定時獲取access_token並保存到redis中


本人原本是想做微信公眾號菜單的創建修改刪除等操作的,但是發現需要access_token,通過閱讀文檔,發現文檔要求有以下幾點:

1.access_token 獲取后有效期是2小時

2.access_token 占用512個字符空間

3.獲取access_token 的url 為(get請求) :  https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

4.請求成功返回的格式為:{"access_token":"ACCESS_TOKEN","expires_in":7200}

 

思路:

1.前提必須是成功獲取到 access_token

2. 項目里需要配置一個定時器,用來定期獲取 access_token

3.成功獲取后應該把access_token妥善保存,比如保存在 數據庫、緩存(本人所選,redis)、配置文件中都可以

 

步驟一:獲取access_token

 1 package com.encore.util;
 2 
 3 import org.json.JSONObject;
 4 
 5 import java.io.BufferedReader;
 6 import java.io.InputStreamReader;
 7 import java.net.HttpURLConnection;
 8 import java.net.URL;
 9 import java.util.List;
10 import java.util.Map;
11 
12 public class WeChatTokenUtil {
13     //獲取access_token的url
14     private static final String BASE_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?";
15     //固定值
16     private static final String GRANT_TYPE = "client_credential";
17     //自己的AppID
18     private static final String APP_ID = "**********";
19     //自己的AppSecret
20     private static final String SECRET = "***********";
21 
22     public static String getToken(){
23         String url = BASE_TOKEN_URL + "grant_type="+GRANT_TYPE+"&appid="+APP_ID+"&secret="+SECRET;
24         try{
25             URL realUrl = new URL(url);
26             // 打開和URL之間的連接
27             HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
28             connection.setRequestMethod("GET");
29             connection.connect();
30             // 獲取所有響應頭字段
31             Map<String, List<String>> map = connection.getHeaderFields();
32             // 遍歷所有的響應頭字段
33             for (String key : map.keySet()) {
34                 System.err.println(key + "--->" + map.get(key));
35             }
36             // 定義 BufferedReader輸入流來讀取URL的響應
37             BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
38             String result = "";
39             String line;
40             while ((line = in.readLine()) != null) {
41                 result += line;
42             }
43             JSONObject jsonObject = new JSONObject(result);
44             return jsonObject.getString("access_token");
45         } catch (Exception e) {
46             System.err.printf("獲取token失敗!");
47             e.printStackTrace(System.err);
48             return "";
49         }
50     }
51 
52 }
View Code

 

步驟二:配置定時器:

在spring的xml中配置:

1 <!-- 定時器配置 -->
2     <task:annotation-driven scheduler="myScheduler"/>
3     <task:scheduler id="myScheduler" pool-size="5"/>
View Code

注意:寫定時方法的類必須在spring能夠掃描的到的包下

 

步驟三:配置redis(如果不用redis可以跳過此步驟,直接把access_token保存到數據庫或者配置文件中就可以了)

1.前提是本機裝了redis,網上有很多教程,本文不做過多介紹,並不復雜

2.引入項目需要的redis依賴

1 <!-- redis 依賴 -->
2       <dependency>
3           <groupId>redis.clients</groupId>
4           <artifactId>jedis</artifactId>
5           <version>2.9.0</version>
6           <type>jar</type>
7       </dependency>
View Code

3.配置reids連接(跟配置jdbc連接類似)

1 redis.host=127.0.0.1
2 redis.port=6379
3 redis.timeout=3000
View Code

4.新建一個reids.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 6 
 7     <context:property-placeholder location="classpath:redis.properties" />
 8 
 9     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" />
10 
11     <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" scope="singleton" >
12         <constructor-arg index="0" ref="jedisPoolConfig" />
13         <constructor-arg index="1">
14             <list>
15                 <bean class="redis.clients.jedis.JedisShardInfo">
16                     <constructor-arg name="host" value="${redis.host}"/>
17                     <constructor-arg name="port" value="${redis.port}"/>
18                     <constructor-arg name="timeout" value="${redis.timeout}"/>
19                 </bean>
20             </list>
21         </constructor-arg>
22     </bean>
23 
24 </beans>
View Code

5.將redis.xml引入到spring的xml中

1 <import resource="redis.xml"/>
View Code

6.編寫一個redis連接池的類,包含安全關閉連接池的方法,同樣也要使這個類能夠被spring所掃描到

 1 package com.encore.service;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.springframework.stereotype.Service;
 5 import redis.clients.jedis.ShardedJedis;
 6 import redis.clients.jedis.ShardedJedisPool;
 7 
 8 import javax.annotation.Resource;
 9 
10 @Service("redisPool")
11 @Slf4j
12 public class RedisPool {
13 
14     @Resource(name = "shardedJedisPool")
15     private ShardedJedisPool shardedJedisPool;
16 
17     public ShardedJedis instance(){
18         return shardedJedisPool.getResource();
19     }
20 
21     public void safeClose(ShardedJedis shardedJedis){
22         try {
23             if (shardedJedis != null){
24                 shardedJedis.close();
25             }
26         }catch (Exception e){
27             log.error("redis 關閉異常", e);
28         }
29     }
30 }
View Code

7.封裝一個類,提供把數據寫入redis和從redis中讀取數據的方法,也要讓這個類被spring所管理

 1 package com.encore.service;
 2 
 3 import org.springframework.stereotype.Service;
 4 import redis.clients.jedis.ShardedJedis;
 5 
 6 import javax.annotation.Resource;
 7 
 8 @Service("redisCacheService")
 9 public class RedisCacheService {
10 
11     // 注入RedisPool
12     @Resource(name = "redisPool")
13     private RedisPool redisPool;
14 
15 
16     /**
17      *  把要存儲的值放進緩存
18      * @param cacheKey 鍵值,可以用來獲取要存儲的值
19      * @param toSavedValue 要存儲的值
20      * @param timeOutSeconds 過期時間 單位為秒
21      */
22     public void saveCache(String cacheKey, String toSavedValue, int timeOutSeconds){
23         if (toSavedValue == null){
24             return;
25         }
26         ShardedJedis shardedJedis =  null;
27         try {
28             shardedJedis = redisPool.instance();
29             shardedJedis.setex(cacheKey, timeOutSeconds, toSavedValue);
30         }catch (Exception e){
31             e.printStackTrace();
32         }finally {
33             redisPool.safeClose(shardedJedis);
34         }
35     }
36 
37     /**
38      * 根據鍵值從緩存中獲取數據
39      * @param cacheKey 緩存的鍵值
40      * @return
41      */
42     public String getFromCache(String cacheKey){
43         ShardedJedis shardedJedis = null;
44         try {
45             shardedJedis = redisPool.instance();
46             String value = shardedJedis.get(cacheKey);
47             return value;
48         }catch (Exception e){
49             return null;
50         }finally {
51             redisPool.safeClose(shardedJedis);
52         }
53     }
54 
55 
56 }
View Code

 

步驟四:實現定時器的方法(這個類要可以被spring掃描的到),實現每1.5小時獲取一次access_token,並將其放到redis,同時保證可以從redis中讀取出來

 1 package com.encore.service;
 2 
 3 import com.encore.util.WeChatTokenUtil;
 4 import org.springframework.scheduling.annotation.Scheduled;
 5 import org.springframework.stereotype.Component;
 6 
 7 import javax.annotation.Resource;
 8 
 9 @Component
10 public class TaskService {
11 
12     @Resource
13     private RedisCacheService redisCacheService;
14 
15     private static final String TOKEN_KEY = "my_wechat_token";
16 
17     @Scheduled(fixedRate= 1000*60*90, initialDelay = 2000)//項目啟動2秒中之后執行一次,然后每90min執行一次,單位都為ms
18     public void getToken(){
19         //1. 獲取token
20         String access_token = WeChatTokenUtil.getToken();
21         System.out.println("從微信服務器獲取的token======"+access_token);
22         redisCacheService.saveCache(TOKEN_KEY, access_token ,60*120);
23         String getToken = redisCacheService.getFromCache(TOKEN_KEY);
24         System.out.println("從redis中獲取的token === "+getToken);
25     }
26 }
View Code

 

最后,在開啟項目進行測試的時候,先把redis服務器打開,經測試,可以正常獲取access_token,也可以存放到redis中,同時也可以從redis中讀取出來,如圖所示,可以從Redis Desktop Manager中看得到存放進去的access_token:

 


免責聲明!

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



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