目的:调用微信上传图片接口时,需要获取用到微信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;
}
}
三、WeiXinUtilsimport 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 "";
}
}
版权声明:本文为qq_33157666原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。