当自己的程序需要访问微信的HTTP接口时,需要传递access_token作为校验的参数。access_token需要通过APPID和APPSecret秘钥来生成,有效期是7200秒,2小时。access_token最好是做成全局变量共享,然后由一个线程定时去刷新,这样可以减少access_token生成的次数,微信服务器对access_token的生成次数有限制。
代码如下,首先是使用HttpClient来发送GET, POST请求的Util类,支持HTTPS
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
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.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
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;
public class WeixinHttpUtil {
/**
* HttpClient连接SSL
*/
public static CloseableHttpClient getHTTPSClient() {
CloseableHttpClient httpclient = null;
try {
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext;
sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
.build();
} catch (Exception e) {
e.printStackTrace();
}
return httpclient;
}
public static String postNameValuePair(CloseableHttpClient httpClient, String url, List<BasicNameValuePair> formparams) {
String responseBody = "";
// 创建httppost
HttpPost httppost = new HttpPost(url);
UrlEncodedFormEntity uefEntity;
try {
uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
httppost.setEntity(uefEntity);
CloseableHttpResponse response = httpClient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
responseBody = EntityUtils.toString(entity, "UTF-8");
}
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseBody;
}
public static String postXml(CloseableHttpClient httpClient, String url, String xml) {
String responseBody = "";
// 创建httppost
HttpPost httppost = new HttpPost(url);
try {
StringEntity paramEntity = new StringEntity(xml);
httppost.setEntity(paramEntity);
httppost.setHeader("Content-Type", "text/xml;charset=UTF-8");
CloseableHttpResponse response = httpClient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
responseBody = EntityUtils.toString(entity, "UTF-8");
}
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseBody;
}
/**
* 发送 get请求
*/
public static String get(CloseableHttpClient httpClient, String url) {
String responseBody = "";
try {
// 创建httpget.
HttpGet httpget = new HttpGet(url);
// 执行get请求.
CloseableHttpResponse response = httpClient.execute(httpget);
try {
// 获取响应实体
HttpEntity entity = response.getEntity();
if (entity != null) {
responseBody = EntityUtils.toString(entity, "UTF-8");
}
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseBody;
}
private static class MyX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}
然后是一个单实例的类来提供acces_token的共享,并创建了一个单线程的定时任务来访问微信服务器获取最新的access_token
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.http.impl.client.CloseableHttpClient;
import com.alibaba.fastjson.JSON;
public class AccessTokenUtil {
private static AccessTokenUtil instance = new AccessTokenUtil();
protected final ScheduledExecutorService executorService;
private final static String APP_ID = "";
private final static String APP_SECRET = "";
private final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;
private AccessTokenGetter accessTokenGetter = new AccessTokenGetter();
public void start(){
//启动定时执行线程池,7000秒刷新一次, Weixin access_token 默认有效期是否7200s
executorService.scheduleWithFixedDelay(accessTokenGetter, 0, 7000, TimeUnit.SECONDS);
}
private AccessTokenUtil(){
executorService = Executors.newScheduledThreadPool(1);
this.start();
}
public static AccessTokenUtil getInstance(){
return instance;
}
public String getAccessToken(){
return accessTokenGetter.getAccessToken();
}
private static class AccessTokenGetter implements Runnable{
private volatile String accessToken = "";
public void run() {
try {
CloseableHttpClient httpClient = WeixinHttpUtil.getHTTPSClient();
String accessTokenJSONStr = WeixinHttpUtil.get(httpClient, ACCESS_TOKEN_URL);
AccessTokenJSON obj = JSON.parseObject(accessTokenJSONStr, AccessTokenJSON.class);
accessToken = obj.getAccess_token();
} catch (Exception e) {
}
}
public String getAccessToken(){
return accessToken;
}
}
public static void main(String[] args){
AccessTokenUtil.getInstance();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Token: " + AccessTokenUtil.getInstance().getAccessToken());
}
}