目的:调用微信上传图片接口时,需要获取用到微信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+"×tamp="+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 ""; } }