当自己的程序需要访问微信的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()); } }