调用微信接口获取jsapi_ticket凭证
直接上代码,可以直接复用
jsp页面:
<script type="text/javascript" src="https://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script type="text/javascript">
$(function () {
wechartInit();
});
function wechartInit() {
var localURL = location.href.split('#')[0];
var targetURL = '/webgetsign.shtml' + '?url=' + localURL;
$.ajax({
url: '/webgetjsapiticket.shtml',//获取签名的接口
data: {
url: localURL
},
type: 'post',
dataType : 'json',
success: function(data) {
if (wx) {
wx.config({
debug: false,
appId: data.appid,// 必填,公众号的唯一标识
timestamp: data.timestamp,// 必填,生成签名的时间戳
nonceStr: data.nonceStr,// 必填,生成签名的随机串
signature: data.signature,// 必填,签名,见附录1
jsApiList: [
'onMenuShareAppMessage', //1.0 分享到朋友
'onMenuShareTimeline', //1.0分享到朋友圈
'updateAppMessageShareData', //1.4 分享到朋友
'updateTimelineShareData', //1.4分享到朋友圈
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () {
var shareData = {
title: 'XXXXXXXXX', // 分享标题
desc: 'XXXXXXXXX', // 分享描述
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'XXXXXXXXX' // 分享图标
};
if(wx.onMenuShareAppMessage){ //微信文档中提到这两个接口即将弃用,故判断
wx.onMenuShareAppMessage(shareData);//1.0 分享到朋友
wx.onMenuShareTimeline(shareData);//1.0分享到朋友圈
}else{
wx.updateAppMessageShareData(shareData);//1.4 分享到朋友
wx.updateTimelineShareData(shareData);//1.4分享到朋友圈
}
});
}
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("莫名其妙出错了:"+XMLHttpRequest.status+"---"+textStatus+"---"+errorThrown);
}
});
}
</script>
后台代码:
@ResponseBody
@RequestMapping(value = "/webgetsign", produces = "text/html;charset=UTF-8")
public String webgetsign(HttpServletRequest request, HttpServletResponse response) throws Exception{
response.setHeader("Access-Control-Allow-Origin","*"); //
//1、获取Ticket
String jsapi_ticket = WeixinConfig.getJSAPITicketInstance();
//System.out.println("jsticked凭证:"+jsapi_ticket);
//2、时间戳和随机字符串
String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳
//System.out.println("accessToken:"+accessToken+"\njsapi_ticket:"+jsapi_ticket+"\n时间戳:"+timestamp+"\n随机字符串:"+noncestr);
//3、获取url
String url=request.getParameter("url");
//4、将参数排序并拼接字符串 //"jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url;
String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url;
//5、将字符串进行sha1加密
String signature =sha1(str);
Map<String, String> paramesMap=new HashMap<String, String>();
paramesMap.put("timestamp", timestamp);
paramesMap.put("nonceStr", noncestr);
paramesMap.put("signature", signature);
paramesMap.put("appid", appid);
// * 发送给朋友: "menuItem:share:appMessage" 分享到朋友圈: "menuItem:share:timeline" 分享到QQ: "menuItem:share:qq" 分享到Weibo: "menuItem:share:weiboApp" */
//System.out.println("参数:"+str+"\n签名:"+signature);
return JSONObject.toJSONString(paramesMap);
}
/**
* 使用SHA1算法对字符串进行加密
* @param str
* @return
*/
public static String sha1(String str) {
if (str == null || str.length() == 0) {
return null;
}
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
调用微信接口代码:
WeixinConfig.java
import java.util.Date;
import com.alibaba.fastjson.JSONObject;
import WeixinUtil;
import model.AccessToken;
import model.JsAPITicket;
public class WeixinConfig {
public static final String APPID= "";
public static final String APPSECRET = "";
// 凭证获取(GET)
public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// jsapi_ticket
public static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
public static String access_token;
public static String js_api_ticket;
//主动调用的请求时间
public static Date access_token_date;
//token的有效时间,默认7200,用于判断是否超时,考虑网络延迟是的减小
public static long accessTokenInvalidTime=7200L;
static {
access_token = getTokenInstance();
js_api_ticket = getJSAPITicketInstance();
}
public static String getTokenInstance(){
if(access_token == null || access_token.equals("") || (new Date().getTime()-access_token_date.getTime())>=((accessTokenInvalidTime-200L)*1000)){
String appid = "你公众号基本设置里的应用id";// 应用ID
String appSecret = "你公众号基本设置里的应用密钥";// (应用密钥)
AccessToken at = WeixinUtil.getAccessToken(appid, appSecret);
access_token = at.getAccessToken();
access_token_date = new Date();
}
return access_token;
}
public static String getJSAPITicketInstance(){
if(js_api_ticket == null || js_api_ticket.equals("") || (new Date().getTime()-access_token_date.getTime())>=((accessTokenInvalidTime-200L)*1000)){
String result = WeixinUtil.getJSApiTicket(getTokenInstance());
JsAPITicket jsApiTicket = JSONObject.parseObject(result, JsAPITicket.class);
js_api_ticket = jsApiTicket.getTicket();
}
return js_api_ticket;
}
}
WeixinUtil.java
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
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 model.AccessToken;
import MyX509TrustManager;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
public class WeixinUtil {
// 凭证获取(GET)
public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// jsapi_ticket
public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
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);
// 当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;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
// ce.getMessage());
ce.printStackTrace();
} catch (Exception e) {
// e.getMessage());
e.printStackTrace();
}
return jsonObject;
}
/**
* 获取access_token
*
* @param appid
* 凭证
* @param appsecret
* 密钥
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret) {
AccessToken accessToken = null;
String requestUrl = token_url.replace("APPID", appid).replace(
"APPSECRET", appsecret);
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setAccessToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
accessToken = null;
// 获取token失败
e.printStackTrace();
}
}
return accessToken;
}
/**
* 获取jsAPIticket
*
* @param accessToken
* @return
*
*/
public static String getJSApiTicket(String accessToken) {
String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN",
accessToken);
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
jsonObject.getString("ticket");
} catch (JSONException e) {
// 获取token失败
e.printStackTrace();
jsonObject = new JSONObject();
}
}
return jsonObject.toString();
}
}
AccessToken.java
/**
* 凭证
*
*/
public class AccessToken {
// 接口访问凭证
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;
}
}
JsAPITicket.java
public class JsAPITicket {
private Integer errcode;
private String errmsg;
private String ticket;
private Integer expires_in;
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public Integer getExpires_in() {
return expires_in;
}
public void setExpires_in(Integer expires_in) {
this.expires_in = expires_in;
}
}
MyX509TrustManager.java
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
* 信任管理器
*
*/
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;
}
}
以上完毕。
附上微信JS接口签名校验地址:
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
可以判断ticket是否过期