欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java微信公眾平臺開發(fā)(6) 微信開發(fā)中的token獲取

 更新時間:2017年04月21日 10:39:02   作者:dapengniao  
這篇文章主要為大家詳細介紹了Java微信公眾平臺開發(fā)第六步,微信開發(fā)中的token獲取,具有一定的參考價值,感興趣的小伙伴們可以參考一下

(一)token的介紹

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

(二)token的獲取參考文檔

獲取的流程我們完全可以參考微信官方文檔:http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html 如圖:

1.png

(三)token獲取流程分析

從公眾平臺獲取賬號的AppID和AppSecret;
token獲取并解析存儲執(zhí)行體;
采用任務(wù)調(diào)度每隔兩小時執(zhí)行一次token獲取執(zhí)行體;

(四)token的獲取流程的具體實現(xiàn)
①獲取appid和appsecret

在微信公眾平臺【開發(fā)】——>【基本配置】中可以查看到我們需要的兩個參數(shù):

1.png

這里我們將他們定義到我們的配置文件【wechat.properties】中,大致代碼為:

#獲取到的appid
appid=wx7e32765bc24XXXX 
#獲取到的AppSecret
AppSecret=d58051564fe9d86093f9XXXXX

②token獲取并解析存儲執(zhí)行體的代碼編寫

由于在這里我們需要通過http的get請求向微信服務(wù)器獲取時效性為7200秒的token,所以我在這里寫了一個http請求的工具類,以方便我們的使用,如下:

package com.cuiyongzhi.wechat.util;
 
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
 
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
 
/**
 * ClassName: HttpUtils
 * 
 * @Description: http請求工具類
 * @author dapengniao
 * @date 2016年3月10日 下午3:57:14
 */
@SuppressWarnings("deprecation")
public class HttpUtils {
 
 /**
  * @Description: http get請求共用方法
  * @param @param reqUrl
  * @param @param params
  * @param @return
  * @param @throws Exception
  * @author dapengniao
  * @date 2016年3月10日 下午3:57:39
  */
 @SuppressWarnings("resource")
 public static String sendGet(String reqUrl, Map<String, String> params)
   throws Exception {
  InputStream inputStream = null;
  HttpGet request = new HttpGet();
  try {
   String url = buildUrl(reqUrl, params);
   HttpClient client = new DefaultHttpClient();
 
   request.setHeader("Accept-Encoding", "gzip");
   request.setURI(new URI(url));
 
   HttpResponse response = client.execute(request);
 
   inputStream = response.getEntity().getContent();
   String result = getJsonStringFromGZIP(inputStream);
   return result;
  } finally {
   if (inputStream != null) {
    inputStream.close();
   }
   request.releaseConnection();
  }
 
 }
 
 /**
  * @Description: http post請求共用方法
  * @param @param reqUrl
  * @param @param params
  * @param @return
  * @param @throws Exception
  * @author dapengniao
  * @date 2016年3月10日 下午3:57:53
  */
 @SuppressWarnings("resource")
 public static String sendPost(String reqUrl, Map<String, String> params)
   throws Exception {
  try {
   Set<String> set = params.keySet();
   List<NameValuePair> list = new ArrayList<NameValuePair>();
   for (String key : set) {
    list.add(new BasicNameValuePair(key, params.get(key)));
   }
   if (list.size() > 0) {
    try {
     HttpClient client = new DefaultHttpClient();
     HttpPost request = new HttpPost(reqUrl);
 
     request.setHeader("Accept-Encoding", "gzip");
     request.setEntity(new UrlEncodedFormEntity(list, HTTP.UTF_8));
 
     HttpResponse response = client.execute(request);
 
     InputStream inputStream = response.getEntity().getContent();
     try {
      String result = getJsonStringFromGZIP(inputStream);
 
      return result;
     } finally {
      inputStream.close();
     }
    } catch (Exception ex) {
     ex.printStackTrace();
     throw new Exception("網(wǎng)絡(luò)連接失敗,請連接網(wǎng)絡(luò)后再試");
    }
   } else {
    throw new Exception("參數(shù)不全,請稍后重試");
   }
  } catch (Exception ex) {
   ex.printStackTrace();
   throw new Exception("發(fā)送未知異常");
  }
 }
 
 /**
  * @Description: http post請求json數(shù)據(jù)
  * @param @param urls
  * @param @param params
  * @param @return
  * @param @throws ClientProtocolException
  * @param @throws IOException
  * @author dapengniao
  * @date 2016年3月10日 下午3:58:15
  */
 public static String sendPostBuffer(String urls, String params)
   throws ClientProtocolException, IOException {
  HttpPost request = new HttpPost(urls);
 
  StringEntity se = new StringEntity(params, HTTP.UTF_8);
  request.setEntity(se);
  // 發(fā)送請求
  @SuppressWarnings("resource")
  HttpResponse httpResponse = new DefaultHttpClient().execute(request);
  // 得到應(yīng)答的字符串,這也是一個 JSON 格式保存的數(shù)據(jù)
  String retSrc = EntityUtils.toString(httpResponse.getEntity());
  request.releaseConnection();
  return retSrc;
 
 }
 
 /**
  * @Description: http請求發(fā)送xml內(nèi)容
  * @param @param urlStr
  * @param @param xmlInfo
  * @param @return
  * @author dapengniao
  * @date 2016年3月10日 下午3:58:32
  */
 public static String sendXmlPost(String urlStr, String xmlInfo) {
  // xmlInfo xml具體字符串
 
  try {
   URL url = new URL(urlStr);
   URLConnection con = url.openConnection();
   con.setDoOutput(true);
   con.setRequestProperty("Pragma:", "no-cache");
   con.setRequestProperty("Cache-Control", "no-cache");
   con.setRequestProperty("Content-Type", "text/xml");
   OutputStreamWriter out = new OutputStreamWriter(
     con.getOutputStream());
   out.write(new String(xmlInfo.getBytes("utf-8")));
   out.flush();
   out.close();
   BufferedReader br = new BufferedReader(new InputStreamReader(
     con.getInputStream()));
   String lines = "";
   for (String line = br.readLine(); line != null; line = br
     .readLine()) {
    lines = lines + line;
   }
   return lines; // 返回請求結(jié)果
  } catch (MalformedURLException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return "fail";
 }
 
 private static String getJsonStringFromGZIP(InputStream is) {
  String jsonString = null;
  try {
   BufferedInputStream bis = new BufferedInputStream(is);
   bis.mark(2);
   // 取前兩個字節(jié)
   byte[] header = new byte[2];
   int result = bis.read(header);
   // reset輸入流到開始位置
   bis.reset();
   // 判斷是否是GZIP格式
   int headerData = getShort(header);
   // Gzip 流 的前兩個字節(jié)是 0x1f8b
   if (result != -1 && headerData == 0x1f8b) {
    // LogUtil.i("HttpTask", " use GZIPInputStream ");
    is = new GZIPInputStream(bis);
   } else {
    // LogUtil.d("HttpTask", " not use GZIPInputStream");
    is = bis;
   }
   InputStreamReader reader = new InputStreamReader(is, "utf-8");
   char[] data = new char[100];
   int readSize;
   StringBuffer sb = new StringBuffer();
   while ((readSize = reader.read(data)) > 0) {
    sb.append(data, 0, readSize);
   }
   jsonString = sb.toString();
   bis.close();
   reader.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 
  return jsonString;
 }
 
 private static int getShort(byte[] data) {
  return (data[0] << 8) | data[1] & 0xFF;
 }
 
 /**
  * 構(gòu)建get方式的url
  * 
  * @param reqUrl
  *   基礎(chǔ)的url地址
  * @param params
  *   查詢參數(shù)
  * @return 構(gòu)建好的url
  */
 public static String buildUrl(String reqUrl, Map<String, String> params) {
  StringBuilder query = new StringBuilder();
  Set<String> set = params.keySet();
  for (String key : set) {
   query.append(String.format("%s=%s&", key, params.get(key)));
  }
  return reqUrl + "?" + query.toString();
 }
 
}

我們在做http請求的時候需要目標服務(wù)器的url,這里在項目中為了方便對url的管理我們在資源目錄下建立了interface_url.properties用于存放目標url,這里我們將請求token的url存入:

#獲取token的url
tokenUrl=https://api.weixin.qq.com/cgi-bin/token

我們需要將我們配置的配置文件在項目初始化后能得到啟動,所以我在這里加入一個項目初始化的代碼實現(xiàn),用于項目啟動初始化interface_url.properties和wechat.properties中的配置:

package com.cuiyongzhi.web.start;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
 
/**
 * ClassName: InterfaceUrlIntiServlet
 * @Description: 項目啟動初始化servlet
 * @author dapengniao
 * @date 2016年3月10日 下午4:08:43
 */
public class InterfaceUrlIntiServlet extends HttpServlet {
 
 private static final long serialVersionUID = 1L;
 
 @Override
 public void init(ServletConfig config) throws ServletException {
  InterfaceUrlInti.init();
 }
 
}

初始化的具體實現(xiàn),將初始化過后的方法都存入到GlobalConstants中方便項目中隨意調(diào)用,如下:

package com.cuiyongzhi.web.start;
 
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
 
import com.cuiyongzhi.web.util.GlobalConstants;
 
/**
 * ClassName: InterfaceUrlInti
 * @Description: 項目啟動初始化方法
 * @author dapengniao
 * @date 2016年3月10日 下午4:08:21
 */
public class InterfaceUrlInti {
 
 public synchronized static void init(){
  ClassLoader cl = Thread.currentThread().getContextClassLoader();
  Properties props = new Properties();
  if(GlobalConstants.interfaceUrlProperties==null){
   GlobalConstants.interfaceUrlProperties = new Properties();
  }
  InputStream in = null;
  try {
   in = cl.getResourceAsStream("interface_url.properties");
   props.load(in);
   for(Object key : props.keySet()){
    GlobalConstants.interfaceUrlProperties.put(key, props.get(key));
   }
    
   props = new Properties();
   in = cl.getResourceAsStream("wechat.properties");
   props.load(in);
   for(Object key : props.keySet()){
    GlobalConstants.interfaceUrlProperties.put(key, props.get(key));
   }
    
  } catch (IOException e) {
   e.printStackTrace();
  }finally{
   if(in!=null){
    try {
     in.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
  return;
 }
 
}

當我們把所有的準備工作都做好了之后我們可以開始真正的去獲取token了,這里我們將獲取到的token解析之后依然存儲到GlobalConstants中方便使用,簡單代碼如下:

package com.cuiyongzhi.wechat.common;
 
import java.util.HashMap;
import java.util.Map;
 
import net.sf.json.JSONObject;
 
import com.cuiyongzhi.web.util.GlobalConstants;
import com.cuiyongzhi.wechat.util.HttpUtils;
 
/**
 * ClassName: WeChatTask
 * @Description: 微信兩小時定時任務(wù)體
 * @author dapengniao
 * @date 2016年3月10日 下午1:42:29
 */
public class WeChatTask {
 /**
  * @Description: 任務(wù)執(zhí)行體
  * @param @throws Exception
  * @author dapengniao
  * @date 2016年3月10日 下午2:04:37
  */
 public void getToken_getTicket() throws Exception {
  Map<String, String> params = new HashMap<String, String>();
  params.put("grant_type", "client_credential");
  params.put("appid", GlobalConstants.getInterfaceUrl("appid"));
  params.put("secret", GlobalConstants.getInterfaceUrl("AppSecret"));
  String jstoken = HttpUtils.sendGet(
    GlobalConstants.getInterfaceUrl("tokenUrl"), params);
  String access_token = JSONObject.fromObject(jstoken).getString(
    "access_token"); // 獲取到token并賦值保存
  GlobalConstants.interfaceUrlProperties.put("access_token", access_token);
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"token為=============================="+access_token);
 }
 
}

(三)采用任務(wù)調(diào)度每隔兩小時執(zhí)行一次token獲取執(zhí)行體

我們閱讀過微信的文檔會發(fā)現(xiàn)我們的token獲取的接口每天是有調(diào)用次數(shù)限制的,為了防止我們業(yè)務(wù)量比較大的情況下token的直接調(diào)用的接口次數(shù)不夠用,所以我們需要根據(jù)token的時效性(7200s)在自己的業(yè)務(wù)服務(wù)器上做到token的緩存并定時獲取,我這里用到的任務(wù)調(diào)度的方式是采用quartz,有關(guān)quartz的使用可以參考文章 http://cuiyongzhi.com/?tags=%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1 ,下面具體代碼的實現(xiàn):

package com.cuiyongzhi.wechat.quartz;
 
import org.apache.log4j.Logger;
 
import com.cuiyongzhi.wechat.common.WeChatTask;
 
public class QuartzJob{
  private static Logger logger = Logger.getLogger(QuartzJob.class);
  /**
   * @Description: 任務(wù)執(zhí)行獲取token
   * @param  
   * @author dapengniao
   * @date 2016年3月10日 下午4:34:26
   */
  public void workForToken() {
    try {
      WeChatTask timer = new WeChatTask();
      timer.getToken_getTicket();
    } catch (Exception e) {
      logger.error(e, e);
    }
  }
 
 
}

這里新建配置文件spring-quartz.xml以方便quartz任務(wù)的管理和啟用,這里將我們需要用到的workForToken()加入到執(zhí)行任務(wù)中:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 
<beans>
 <!-- 要調(diào)用的工作類 -->
 <bean id="quartzJob" class="com.cuiyongzhi.wechat.quartz.QuartzJob"></bean>
  
 <!-- 定義調(diào)用對象和調(diào)用對象的方法 -->
 <bean id="jobtaskForToken"
  class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
  <!-- 調(diào)用的類 -->
  <property name="targetObject">
   <ref bean="quartzJob" />
  </property>
  <!-- 調(diào)用類中的方法 -->
  <property name="targetMethod">
   <value>workForToken</value>
  </property>
 
 </bean>
 <!-- 定義觸發(fā)時間 -->
 <bean id="doTimeForToken" class="org.springframework.scheduling.quartz.CronTriggerBean">
  <property name="jobDetail">
   <ref bean="jobtaskForToken" />
  </property>
  <!-- cron表達式 -->
  <property name="cronExpression">
   <value>0 0/1 * * * ?</value>
  </property>
 </bean>
 
 
 <!-- 總管理類 如果將lazy-init='false'那么容器啟動就會執(zhí)行調(diào)度程序 -->
 <bean id="startQuertz" lazy-init="false" autowire="no"
  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
   <list>
    <ref bean="doTimeForToken" />
   </list>
  </property>
 </bean>
 
</beans>

這里我為了測試將執(zhí)行間隔時間設(shè)置成了1分鐘一次,根據(jù)需要可以自行修改執(zhí)行時間;最后我們需要在我們的web.xml啟動項中開啟quartz的使用:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:spring.xml,classpath:spring-mybatis.xml,classpath:spring-quartz.xml</param-value>
  <!-- ,classpath:spring-quartz.xml 用于做任務(wù)調(diào)度 任務(wù)定時都可以 -->
 </context-param>

當這一切都準備完畢之后我們啟動項目,會發(fā)現(xiàn)每間隔一分鐘就會有token獲取到,這里我是將其存儲在項目變量中,但是如果需要考慮到項目橫向擴展這里建議將token存儲到緩存中;運行結(jié)果如下:

1.png

那么到這里token的獲取和保存就基本講完了,下一篇將講述【多媒體消息的回復(fù)】,感謝你的翻閱,如果有需要源碼或有疑問可以留言!

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java8新特性教程之time包使用總結(jié)

    java8新特性教程之time包使用總結(jié)

    Java8新增了date和time的util包,下面這篇文章主要給大家介紹了關(guān)于java8新特性教程之time包使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-01-01
  • SpringBoot結(jié)合JWT實現(xiàn)用戶登錄、注冊、鑒權(quán)

    SpringBoot結(jié)合JWT實現(xiàn)用戶登錄、注冊、鑒權(quán)

    用戶登錄、注冊及鑒權(quán)是我們基本所有系統(tǒng)必備的,也是很核心重要的一塊,本文主要介紹了SpringBoot結(jié)合JWT實現(xiàn)用戶登錄、注冊、鑒權(quán),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-05-05
  • 快速了解Maven

    快速了解Maven

    這篇文章主要介紹了快速了解Maven,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • Java AbstractMethodError案例分析詳解

    Java AbstractMethodError案例分析詳解

    這篇文章主要介紹了Java AbstractMethodError案例分析詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java編程關(guān)于子類重寫父類方法問題的理解

    Java編程關(guān)于子類重寫父類方法問題的理解

    這篇文章主要介紹了Java編程關(guān)于子類重寫父類方法問題的理解,分享了有關(guān)子類重寫父類的實例,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Java的CGLIB動態(tài)代理深入解析

    Java的CGLIB動態(tài)代理深入解析

    這篇文章主要介紹了Java的CGLIB動態(tài)代理深入解析,CGLIB是強大的、高性能的代碼生成庫,被廣泛應(yīng)用于AOP框架,它底層使用ASM來操作字節(jié)碼生成新的類,為對象引入間接級別,以控制對象的訪問,需要的朋友可以參考下
    2023-11-11
  • 異常排查記錄amqp協(xié)議鏈接陷阱

    異常排查記錄amqp協(xié)議鏈接陷阱

    這篇文章主要介紹了一次關(guān)于amqp協(xié)議鏈接陷阱-An?unexpected?connection?driver?error?occured的異常排查記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-02-02
  • mybatis trim標簽的使用詳解

    mybatis trim標簽的使用詳解

    這篇文章主要介紹了mybatis trim標簽的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Java常量池知識點總結(jié)

    Java常量池知識點總結(jié)

    本篇文章給大家通過理論原理等方便徹底分析了Java常量池的相關(guān)知識,有興趣的朋友閱讀學習下吧。
    2017-12-12
  • Java中 this和super的用法與區(qū)別小結(jié)

    Java中 this和super的用法與區(qū)別小結(jié)

    在Java的學習與開發(fā)者我們經(jīng)常遇到this和super關(guān)鍵字,本文主要介紹了Java中 this和super的用法與區(qū)別小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12

最新評論