java获取微信的accessToken和ticket

目的:调用微信上传图片接口时,需要获取用到微信accessToken和ticket,下面主要说明怎么获取

一、controller方法

public Map<String,Object> weixinInfo(){
    try {
        //1、获取AccessToken jsapi_ticket
        String accessToken="";
        String jsapiTicket="";
        Map<String,String> tokenMap=AccessTokenUtils.getAccessToken();////AccessTokenUtils见第二步
        if(tokenMap!=null){
            accessToken =tokenMap.get("access_token");
            jsapiTicket =tokenMap.get("jsapi_ticket");
        }
        //3、时间戳和随机字符串  
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串  
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳  
        //4、获取url
        String url = R.getRequest().getScheme()+"://"+ R.getRequest().getServerName()+R.getRequest().getRequestURI();
        if(StringUtils.isNoneBlank(R.getRequest().getQueryString())){
            url = R.getRequest().getScheme()+"://"+ R.getRequest().getServerName()+R.getRequest().getRequestURI()+"?"+R.getRequest().getQueryString();
        }
        //5、将参数排序并拼接字符串  
        String str = "jsapi_ticket="+jsapiTicket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;  
        logger.info("参数拼接的字符串:"+str);
        //6、将字符串进行sha1加密  
        String signature =WeiXinUtils.SHA1(str); 
        logger.info("签名:"+signature);
        Map<String,Object> data=new HashMap<>();
        data.put("timestamp", timestamp);
        data.put("nonceStr", noncestr);
        data.put("signature", signature);
        data.put("accessToken", accessToken);
        data.put("appId",Global.getConfig("wx_appid"));
        return ApiUtils.getMap(ApiUtils.STATUS_OK,"获取成功",data,null);
    }catch(Exception e){
        logger.error("获取微信信息的错误",e);
        return ApiUtils.getMap(ApiUtils.STATUS_SERVER_ERROR,"服务器发生错误",null,null);
    }
}
 
 

二、AccessTokenUtils

/**
 * access_token是公众号的全局唯一接口调用凭据
 * sapi_ticket是公众号用于调用微信JS接口的临时票据
 * access_token的每天调用限额2000次
 * 长期存储access_token
 * */
public class AccessTokenUtils {
    private static Logger log = LoggerFactory.getLogger(MenuManager.class);
    private static Map<String, String> accessTokenMap = new HashMap<>();
    public static Map<String, String> getAccessToken() {
        String time = accessTokenMap.get("time");
        String accessToken = accessTokenMap.get("access_token");
        Long nowDate = new Date().getTime();
        if (accessToken != null && time != null && nowDate - Long.parseLong(time) < (1.5*60*60*1000)) {
            log.info("accessToken存在,且没有超时 , 返回accessTokenMap");
            return accessTokenMap;
        }
        synchronized (AccessTokenUtils.class) {
            if(accessToken != null && time != null && nowDate - Long.parseLong(time) < (1.5*60*60*1000)) {
                log.info("accessToken存在,且没有超时 , 返回accessTokenMap");
                return accessTokenMap;
        } 
        log.info("accessToken 超时 , 或者不存在 , 重新获取");
        try {
            String access_token=WeiXinUtils.getAccessToken();////WeiXinUtils见第三步
            log.info("access_token:"+access_token);
            //"这里是直接调用微信的API去直接获取 accessToken 和Jsapi_ticket 获取";
            String jsapi_ticket =WeiXinUtils.getTicket(access_token);
            log.info("jsapi_ticket:"+jsapi_ticket);
            //"获取jsapi_token";
            accessTokenMap.put("time", nowDate + "");
            accessTokenMap.put("access_token", access_token);
            accessTokenMap.put("jsapi_ticket", jsapi_ticket);
            log.info("获取的access_token:"+accessTokenMap.get("access_token"));
            log.info("获取的jsapi_ticket:"+accessTokenMap.get("jsapi_ticket"));
        } catch (Exception e) {
            log.error("微信服务器发生错误",e);
        }
    }
    return accessTokenMap;        
}
}
三、WeiXinUtils 
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletResponse;

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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class WeiXinUtils {
	
		
	/** 
	 * access_token是公众号的全局唯一接口调用凭据
	 * */
	public static String getAccessToken(){
		String accessToken = "";
		String grantType = "client_credential";// 获取access_token填写client_credential
		String appId ="自己微信公众号的appId";// 第三方用户唯一凭证
		String secret = "自己微信公众号的密钥";// 第三方用户唯一凭证密钥,即appsecret
		// 这个url链接地址和参数皆不能变
		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grantType + "&appid=" + appId + "&secret="+ secret;
		try {
			URL urlGet = new URL(url);
			HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
			http.setRequestMethod("GET"); // 必须是get方式请求
			http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			http.setDoOutput(true);
			http.setDoInput(true);
			System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
			System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
			http.connect();
			InputStream is = http.getInputStream();
			int size = is.available();
			byte[] jsonBytes = new byte[size];
			is.read(jsonBytes);
			String message = new String(jsonBytes, "UTF-8");
			logger.debug("获取access_token返回的message:"+message);
			JSONObject demoJson = JSON.parseObject(message);
			logger.info("获取access_token返回的json:"+demoJson);
			accessToken = demoJson.getString("access_token");
			logger.info("新获取的access_token:"+accessToken);
			is.close();
		}catch (Exception e){
			logger.debug("获取access_token发生异常",e);
		}
		return accessToken;
	}
	
	/**
	 * sapi_ticket是公众号用于调用微信JS接口的临时票据,获得jsapi_ticket之后,就可以生成JSSDK权限验证的签名了
	 * 参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 
	 * @param accessToken
	 * @return
	 */
	public static String getTicket(String accessToken) {
		String ticket = null;
		String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";// 这个url链接和参数不能变
		try {
			URL urlGet = new URL(url);
			HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
			http.setRequestMethod("GET"); // 必须是get方式请求
			http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			http.setDoOutput(true);
			http.setDoInput(true);
			System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
			System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
			http.connect();
			InputStream is = http.getInputStream();
			int size = is.available();
			byte[] jsonBytes = new byte[size];
			is.read(jsonBytes);
			String message = new String(jsonBytes, "UTF-8");
			JSONObject demoJson = JSON.parseObject(message);
			ticket = demoJson.getString("ticket");
			is.close();
		} catch (Exception e) {
			logger.error("获取ticket发生错误", e);  
		}
		return ticket;
	}

	public static String SHA1(String decript) {
		try {
			MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
			digest.update(decript.getBytes());
			byte messageDigest[] = digest.digest();
			// Create Hex String
			StringBuffer hexString = new StringBuffer();
			// 字节数组转换为 十六进制 数
			for (int i = 0; i < messageDigest.length; i++) {
				String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexString.append(0);
				}
				hexString.append(shaHex);
			}
			return hexString.toString();

		} catch (NoSuchAlgorithmException e) {
			logger.error("SHA1发生错误", e);  
		}
		return "";
	}
}


猜你喜欢

转载自blog.csdn.net/qq_33157666/article/details/80158519