错误情况概述:
启动应用之后,微信调用 相机拍照 等接口是可以正常使用的, 但是过了一段时间(2个小时左右--token/jsapi_ticket的过期时间),微信调用相机拍照的功能失效,启用debug模式:
//步骤三:通过config接口注入权限验证配置
wx.config({
debug: true,
报错:invalide signature....
利用调试接口调试:
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
在 jsapi_ticket: 输入本次失败时的jsapi_ticket, 红色信息显示:jsapi_ticket 过期!
所以原因显然是 过了2个小时之后,jsapi_ticket的获取失败!
查看想代码:
核心代码:
@Override
public void run()
{ while(true)
{
try{
HttpsURLConnection conn = HttpUtil.initHttpsConnection(accessTokenUrl, "GET");
String result = HttpUtil.getHttpsContent(conn, "utf-8"); JSONObject json = null;
if(result != null)
json = JSON.parseObject(result); if(json != null){
System.out.println("--------------AccessTokenJsapiTicketThread.222");
accessToken = new AccessToken(json.getString("access_token"), json.getLong("expires_in"));
System.out.println(JSON.toJSONString(json));
// 再获取jsapi_ticket
jsapiTicketUrl += accessToken.getAccess_token() + "&type=jsapi";
conn = HttpUtil.initHttpsConnection(jUrl, "GET");
result = HttpUtil.getHttpsContent(conn, "utf-8");
if(result != null){
json = JSON.parseObject(result);
if(json != null && json.getString("errmsg").equals("ok")){
jsapiTicket = new JsapiTicket(json.getString("errcode"), json.getString("errmsg"),
json.getString("ticket"), json.getLong("expires_in"));
System.out.println(JSON.toJSONString(json));
}else{
System.out.println(json.toJSONString());
System.out.println("get jsapiTicket failed----");
}
}
}else{
System.out.println("get access_token failed----");
}
}catch(IOException e){
e.printStackTrace();
} System.out.println("--------------AccessTokenJsapiTicketThread.444");
try{
if(null != accessToken){
Thread.sleep(60 * 1000); // 如果access_token为null,60秒后再获取
// Thread.sleep((accessToken.getExpire_in() - 200) * 1000); // 休眠7000秒
}else{
Thread.sleep(60 * 1000); // 如果access_token为null,60秒后再获取
}
}catch(InterruptedException e){
System.out.println("--------------AccessTokenJsapiTicketThread.555");
try{
Thread.sleep(60 * 1000);
}catch(InterruptedException e1){
e1.printStackTrace();
}
}
}
}
后台是 servlet随服务器启动的一个线程,每隔2小时运行一次,获取 token 和 jsapi_ticket.
关键的地方,在第二次获取 jsapi_ticket 的地址是有问题的:
jsapiTicketUrl += accessToken.getAccess_token() + "&type=jsapi";
这里导致 第二次 获取 jsapi_ticket 时,携带上了 第一次的 token,也就是携带上两个 token.
第二次的地址变成了:
https://api.weixin.qq.com/cgi-bin/ticket/getticket
?access_token=
HETAdAEwtAsz3GDeKwBxSq3JZt9FrD99vJc2Bvnp5ZmfU7BDVUR78TznZ8oQLmIGOqXfXOPYaJ8OlXBEdwlulf-XGkF1_K9FeHFUGndNIUIUMHjAEAEWR
&type=jsapi
qNpzWXz_d7GT1vchxHUuz5g5jqrwBb2OR5CXd7LldeDGsCa-8d8WQZkfDA157tcn_NmPglp-92c5AqTyqXTcM7aVG-Shw586QYjxmMVyrUxfz-P2GspidfCGAoEwvUsrKSHeAAARZO&
type=jsapi
可以看到 重复了 一次 access_token 参数。所以导致了 获取 jsapiTicket 失败。
修改就极其简单了:
String tmpUrl = jsapiTicketUrl + accessToken.getAccess_token() + "&type=jsapi";
conn = HttpUtil.initHttpsConnection(tmpUrl, "GET");
result = HttpUtil.getHttpsContent(conn, "utf-8");
定义一个临时变量,不要直接修改 jsapiTicketUrl 这个类的属性了。
总结:第一次成功,后面都失败,应该想到是第二次的参数有问题了。
网上看到很多人遇到{"errcode":40097,"errmsg":"invalid args hint: [vjNe7xxxxxx8vr19]"}这个错误,基本没有有价值的信息。还是自己调试解决问题。
记录下,方便其他遇到相同问题的筒子。该错误一定是:url 的参数有错误。