java开发微信之accesstoken获取

2 篇文章 0 订阅

在做微信公众号开发的时候,避免不了要获取accesstoken。

accesstoken有一些限制:

1、accesstoken得到后有一个有效时间限制。

2、accesstoken请求接口有访问次数限制。

为此我们要在accesstoken即将过期的时候去请求新的accesstoken,并将accesstoken保存起来,方便直接使用,而不是每次都要去获取:

Token实体类——保存accessToken跟有限期:

/**
 * Token——微信
 * @author 胡汉三
 *
 * 2017年3月31日 下午3:37:18
 */
public class Token {
	// 接口访问凭证
    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;
    }
}
CommonUtil请求接口的工具类——向微信发送http请求:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfkj.xfcamp.wechat.pojo.Token;

/**
 * http请求工具类
 * @author 胡汉三
 *
 * 2017年3月31日 下午3:46:05
 */
public class CommonUtil {
	
    private static Logger log = LoggerFactory.getLogger(CommonUtil.class);

    // 凭证获取(GET)——access_token
    public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    // 微信JSSDK的ticket请求URL地址——jsapi_ticket 
    public final static String weixin_jssdk_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; 
    
    /**
     * 发送https请求
     * 
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return rootNode(通过rootNode.get(key)的方式获取json对象的属性值)
     */
    public static JsonNode httpsRequest(String requestUrl, String requestMethod, String outputStr) {
    	ObjectMapper mapper = new ObjectMapper();
    	JsonNode rootNode = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            conn.setRequestMethod(requestMethod);
            
            if("GET".equalsIgnoreCase(requestMethod)) conn.connect();

            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            rootNode = mapper.readTree(buffer.toString());
        } catch (ConnectException ce) {
            log.error("连接超时:{}", ce);
        } catch (Exception e) {
            log.error("https请求异常:{}", e);
        }
        return rootNode;
    }

    /**
     * 获取接口访问凭证
     * 
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static Token getToken(String appid, String appsecret) {
        Token token = null;
        String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 发起GET请求获取凭证
        JsonNode rootNode = httpsRequest(requestUrl, "GET", null);

        if (null != rootNode) {
            token = new Token();
            token.setAccessToken(rootNode.get("access_token").textValue());
            token.setExpiresIn(toInt(rootNode.get("expires_in").toString()));
        }
        return token;
    }
    
    
    /**
     * 获取接口访问凭证高级
     * 
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static Token getTokenByOauth(String appid, String appsecret) {
        Token token = null;
        String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 发起GET请求获取凭证
        JsonNode rootNode = httpsRequest(requestUrl, "GET", null);

        if (null != rootNode) {
            token = new Token();
            token.setAccessToken(rootNode.get("access_token").textValue());
            token.setExpiresIn(toInt(rootNode.get("expires_in").toString()));
        }
        return token;
    }
    
    /**
     * URL编码(utf-8)
     * 
     * @param source
     * @return
     */
    public static String urlEncodeUTF8(String source) {
        String result = source;
        try {
            result = java.net.URLEncoder.encode(source, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }
    
    
    public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
    
    /**
     * 调用微信JS接口的临时票据
     * 
     * @param access_token 接口访问凭证
     * @return
     */
    public static String getJsApiTicket(String access_token) {
        String requestUrl = weixin_jssdk_ticket_url.replace("ACCESS_TOKEN", access_token);
        // 发起GET请求获取凭证
        JsonNode rootNode = httpsRequest(requestUrl, "GET", null);
        String ticket = null;
        if (null != rootNode) {
        	ticket = rootNode.get("ticket").textValue();
        }
        return ticket;
    }
    
    
    public static Integer toInt(String str){
    	if(str == null || str.equals("")){
    		return null;
    	}
    	return Integer.valueOf(str);
    }
}
MyX509TrustManager——信任管理器:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;

/**
 * 信任管理器
 * @author 胡汉三
 *
 * 2017年3月31日 下午3:47:14
 */
public class MyX509TrustManager implements X509TrustManager {

    // 检查客户端证书
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 检查服务器端证书
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 返回受信任的X509证书数组
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
TokenThread线程——获取并保存accessToken:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.yfkj.xfcamp.wechat.pojo.Token;
import com.yfkj.xfcamp.wechat.util.CommonUtil;

/**
 * 微信Token线程
 * @author 胡汉三
 *
 * 2017年3月31日 下午4:59:53
 */
public class TokenThread implements Runnable{
	private static final Log log = LogFactory.getLog(TokenThread.class);
	public static String appid= "";
	public static String appsecret = "";
	public static Token token = null;
	public static String jsapi_ticket =""; 
	
	@Override
	public void run() {
		while(true){
			try{
				token = CommonUtil.getToken(appid, appsecret);
				jsapi_ticket = CommonUtil.getJsApiTicket(token.getAccessToken());
				if(null!=token){
					log.info("获取access_token成功");
					log.info("accesstoken初始化成功:"+token.getAccessToken());
					System.out.println("accesstoken初始化成功:"+token.getAccessToken());
					//有效期(秒)减去200秒,乘以1000(毫秒)——也就是在有效期的200秒前去请求新的token
					Thread.sleep((token.getExpiresIn() - 200) * 1000);  
				}else{
					//等待一分钟,在次请求
					Thread.sleep(60*1000);
				}
			}catch(Exception e){
				try{
					//等待一分钟,在次请求
					Thread.sleep(60*1000);
				}catch(Exception e1){
					log.error(e1);
				}
				log.error(e);
			}
		}
		
	}

}
因为是javaWeb项目,需要配置一个Servlet来启动TokenThread

web.xml

<!-- 微信Token -->
	<servlet>
	    <servlet-name>initServlet</servlet-name>
	    <servlet-class>com.yfkj.xfcamp.wechat.InitAccessTokenServlet</servlet-class>
	    <init-param>
	      <param-name>appid</param-name>
	      <param-value>wx79d605bf256d71ee</param-value>
	    </init-param>
	    <init-param>
	      <param-name>appsecret</param-name>
	      <param-value>daaf3c82d2b53eb83a82e36f0a76d6f7</param-value>
	    </init-param>
	    <load-on-startup>0</load-on-startup>
	</servlet>
InitAccessTokenServlet:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * 启动定时获取Token线程——Servlet
 * @author 胡汉三
 *
 */
public class InitAccessTokenServlet extends HttpServlet{
	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(InitAccessTokenServlet.class);
	
	public void init() throws ServletException {
		//获取web.xml中配置的参数
		TokenThread.appid = getInitParameter("appid");
		TokenThread.appsecret = getInitParameter("appsecret");
		
		log.info("weixin api appid :"+TokenThread.appid);
		log.info("weixin api appsecret:"+ TokenThread.appsecret);
		
		if("".equals(TokenThread.appid) || "".equals(TokenThread.appsecret)){
			log.error("appid和appsecret未给出");
		}else {
			new Thread(new TokenThread()).start();
			//System.out.println("accesstoken初始化成功");
		}
	}
}
在其它地方要用accessToken的时候,直接使用TokenThread.token就OK啦!







评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BUG胡汉三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值