1. 程式人生 > >微信測試號開發之四 獲取access_token和jsapi_ticket

微信測試號開發之四 獲取access_token和jsapi_ticket

access_token:公眾號的全域性唯一介面呼叫憑據,公眾號呼叫各介面時都需使用access_token。開發者需要進行妥善儲存。access_token的儲存至少要保留512個字元空間。access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access_token失效。

jsapi_ticket:jsapi_ticket是公眾號用於呼叫微信JS介面的臨時票據。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由於獲取jsapi_ticket的api呼叫次數非常有限,頻繁重新整理jsapi_ticket會導致api呼叫受限,影響自身業務,開發者必須在自己的服務全域性快取jsapi_ticket 。

由於上述兩個標識獲取都有限制,而且有效期是兩個小時,所以開發時設定為每一小時獲取一次

(一):匯入httpclient依賴和jackson依賴

<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-cache</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.1.2</version>
</dependency>


<!-- jack json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.3</version>
</dependency>

(二):封裝httpclient處理get和post請求

import java.io.IOException;
import java.util.List;


import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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.util.EntityUtils;


import com.fasterxml.jackson.databind.ObjectMapper;
public class CommonUtils {

private static HttpClient CLIENT = new DefaultHttpClient();

private static ObjectMapper MAPPER = new ObjectMapper();

public static String APPID ="wx273a3bf59a7d2fee";

public static String SECRET="0ca672094780b3ecf9cedcf35891b129";

/**
* 根據url獲取返回物件
* @param <T>
* @param url
* @return 
* @throws Exception
*/
public static <T> T returnMsg(String url,Class<T> clazz) throws Exception{
HttpPost msgPost = new HttpPost(url);
String str = EntityUtils.toString(CLIENT.execute(msgPost).getEntity(),"UTF-8");
return MAPPER.readValue(str, clazz);
}


/**
* httpclient模擬get請求
*/
public static String Get(String url) throws Exception{
HttpGet httpGet = new HttpGet(url);
String str = EntityUtils.toString(CLIENT.execute(httpGet).getEntity(),"UTF-8");
return str;
}

/**
* http模擬post請求,請求引數是json資料
* @param url
* @param param
* @return
* @throws IOException 
* @throws Exception 
*/
public static String Post_Json(String url, String param) throws Exception{
HttpPost httpPost = new HttpPost(url);
//防止引數亂碼
        httpPost.addHeader("Content-type","application/json; charset=utf-8");  
        httpPost.setEntity(new StringEntity(param, "UTF-8"));
        //執行請求
        HttpResponse execute = CLIENT.execute(httpPost);
        String resp = EntityUtils.toString(execute.getEntity());
        return resp;

}

/**
* httpclient模擬表單提交
* @param url
* @param param
* @return
* @throws Exception
*/
public static String Post_From(String url, List<NameValuePair> list) throws Exception{
HttpPost httpPost = new HttpPost(url);
//防止引數亂碼
        httpPost.addHeader("Content-type","application/json; charset=utf-8");  
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
        httpPost.setEntity(entity);
        //執行請求
        HttpResponse execute = CLIENT.execute(httpPost);
        String resp = EntityUtils.toString(execute.getEntity());
        return resp;
}


}

(三):獲取access_token和jsapi_ticket

import org.springframework.stereotype.Service;


import com.mote.weixin.utils.CommonUtils;


/**
 * 定時重新整理access_token--微信全域性憑證
 * 定時重新整理jsapi_ticket--呼叫微信js介面的臨時票據
 * @author lenovo
 *
 */
@Service("tokenService")
public class TokenService {

private String access_token;
private String jsapi_ticket;

public String getAccess_token() {
return access_token;
}


public void setAccess_token(String access_token) {
this.access_token = access_token;
}


public String getJsapi_ticket() {
return jsapi_ticket;
}


public void setJsapi_ticket(String jsapi_ticket) {
this.jsapi_ticket = jsapi_ticket;
}


/**
* 將該方法配置成定時任務,程式啟動後五秒自動呼叫,
* 之後每隔一小時重新整理一次
*/
public void flush(){

System.out.println("===================我被呼叫了=================");

try {
//獲取access_token
String accessToken = CommonUtils.getAccessToken();
this.access_token = accessToken;

//獲取jsapi_ticket
String jsApiTicket = CommonUtils.getJsApiTicket(accessToken);
this.jsapi_ticket = jsApiTicket;


} catch (Exception e) {
System.out.println("重新整理access_token失敗");
e.printStackTrace();
}

}

}

(四):定義AccessToken物件,然後在CommonUtils中新增獲取access_token和jsapi_ticket的方法

public class AccessToken {
	// 介面訪問憑證
	private String accessToken;
	// 憑證有效期,單位:秒
	private int expiresIn;

	public String getAccessToken() {
		return accessToken;
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}

	public int getExpiresIn() {
		return expiresIn;
	}

	public void setExpiresIn(int expiresIn) {
		this.expiresIn = expiresIn;
	}
}
/**
* 獲取access_token
* @return
* @throws Exception
*/
public static String getAccessToken() throws Exception{
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+SECRET+"";
AccessToken token = returnMsg(url, AccessToken.class);
return token.getAccessToken();
}

/**
     * 獲取呼叫微信JS介面的臨時票據
     * 
     * @param access_token 微信全域性憑證
     * @return
* @throws IOException 
* @throws Exception 
     */
    public static String getJsApiTicket(String access_token) throws Exception{
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
        // 發起GET請求獲取憑證
        String resq = Get(url);
        JsonNode tree = MAPPER.readTree(resq);
        return tree.get("ticket").toString().replaceAll("\"", "");
    }

(五):配置TokenService中的flush方法,使其生效

注意:引入xml約束

xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

配置如下:

<!-- 如果TokeService添加了註解,bean可以省略 -->
<bean id="tokenService" class="com.mote.wx.service.TokenService">
</bean>
<!-- spring自帶的定時重新整理任務 -->
<task:scheduled-tasks>
   <!-- 程式啟動5秒後執行方法,之後每隔一小時執行 -->
<task:scheduled ref="tokenService" method="flush" initial-delay="5000" fixed-delay="3600000" />
<!-- <task:scheduled ref="statJob" method="statLgj" cron="0 59 23 * * ?" /> -->
</task:scheduled-tasks>