//前段代码 wx.config是后端返回的 $.ajax({ type: "post", url: 'jssdk.do',//后台提供的接口 data: { type: "signature", url: window.location.href.split("#")[0], weixinidx: 1 }, cache: false, dataType: 'json', success: function (res) { console.log(res,111); if (res.code==200) { var con = res.data; wx.config( { debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数 注当debug为true可以看到和后端返回的数据 appId: con.appId, timestamp: con.timestamp, // 必填,生成签名的时间戳 nonceStr: con.noncestr, // 必填,生成签名的随机串 signature: con.signature,// 必填,签名 jsApiList: ['scanQRCode']// 必填,需要使用的JS接口列表scanQRCode为扫一扫权限 }); wx.ready(function () { wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有 success: function (res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 //alert(result) // callback(result) }, error:function(res){ alert(res) } }); }) } }, fail: function (e) { layer.msg(e.msg) } });
后端代码
JSSDKBean 返回给前端的信息
public class JSSDKBean implements Serializable { private String url; private String jsapi_ticket; private String noncestr; private String timestamp; private String signature; private String appId; private String access_token; }
WechatVerificationBean正常来说就是设置
jsapi_ticket和access_token
过期时间之类的
public class WechatVerificationBean implements Serializable { private String type; private String createTime; private String certificationTime; private String parameterValue;}
工具类
JsapiTicketUtil
public class JsapiTicketUtil { private static final Logger log = LoggerFactory.getLogger(JsapiTicketUtil.class); /** * * 模拟get请求 * * @param url * @param charset * @param timeout * @return */ public static String sendGet(String url, String charset, int timeout) { String result = ""; try { URL u = new URL(url); try { URLConnection conn = u.openConnection(); conn.connect(); conn.setConnectTimeout(timeout); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset)); String line = ""; while ((line = in.readLine()) != null) { result = result + line; } in.close(); } catch (IOException e) { return result; } } catch (MalformedURLException e) { return result; } return result; } /** * * 获取acess_token * * @return */ public static String getAccessToken() { //我是把appid 、appSecret 放在了
public static ThreadLocal<ConstantsJsSdkBean> tl = new ThreadLocal<>();ConstantsJsSdkBean里边只有appid 、appSecret两个属性
ConstantsJsSdkBean constantsJsSdkBean = Common01ScanController.tl.get(); // 应用ID String appid = constantsJsSdkBean.getAppId(); // (应用密钥) String appSecret = constantsJsSdkBean.getAppSecret(); String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appSecret; log.info("url :{}",url); String backData = sendGet(url, "utf-8", 10000); log.info("backData :{}",backData); String accessToken = (String) JSONUtil.parseObj(backData, false, true).get("access_token"); return accessToken; } /** * * 获取jsapiTicket * * @return */ public static String getJSApiTicket() { // 获取token String acess_token = JsapiTicketUtil.getAccessToken(); String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acess_token + "&type=jsapi"; log.info("获取jsapiTicket的url :{}",urlStr); String backData = sendGet(urlStr, "utf-8", 10000); log.info("获取jsapiTicket:backData :{}",backData); String ticket = (String) JSONUtil.parseObj(backData, false, true).get("ticket"); return ticket; }
WxVerificationUtil 改进的 没做缓存 应该是作缓存的
public class WxVerificationUtil { private static final Logger log = LoggerFactory.getLogger(WxVerificationUtil.class); public static WechatVerificationBean getWxVerification(String type, WechatVerificationBean wechatVerification/*, IWeChatVerificationService weChatVerificationService*/) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String beginTime = simpleDateFormat.format(new Date()); log.info("beginTime.compareTo(wechatVerification.getCertificationTime()) > 0:{}", beginTime.compareTo(wechatVerification.getCertificationTime()) > 0); if (beginTime.compareTo(wechatVerification.getCertificationTime()) > 0) { log.info("验证信息已失效,开始重新获取"); if ("access_token".equals(type)) { refreshAccessToken(wechatVerification/*, weChatVerificationService*/); Common01ScanController.map.put("access_token",wechatVerification); } if ("jsapi_ticket".equals(type)) { refreshJsapiTicket(wechatVerification/*, weChatVerificationService*/); Common01ScanController.map.put("jsapi_ticket",wechatVerification); } } return wechatVerification; } /** * @param wechatVerification * @throws * @description: 刷新access_token * @return: void */ public static void refreshAccessToken(WechatVerificationBean wechatVerification/*, IWeChatVerificationService weChatVerificationService*/) { String accessToken = JsapiTicketUtil.getAccessToken(); wechatVerification.setParameterValue(accessToken); //token默认是7200秒过期,但是如果有第二地方也请求同一个token的话,那么第一个token会在5分钟之内过期 //由于现在的多个环境使用同一个微信公众号的,所以这里只缓存4分钟 //正式环境缓存时长应该是7200s,也就是120分钟,但是考虑服务器时间差等因素,缓存60分钟即可 //7200后面可能会变化,此处暂时没有做这块设定,到时候用系统参数配置要缓存的时长,即可实现变化的配置 wechatVerification.setCertificationTime(String.valueOf(DateUtil.offsetMinute(DateUtil.parse(DateUtil.now()), 4))); log.info("获取accessToken成功:{}", accessToken); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); wechatVerification.setCreateTime(simpleDateFormat.format(new Date())); // weChatVerificationService.megerWechatVerification(wechatVerification); } /** * @param wechatVerification * @throws * @description: 刷新jsapi_ticket * @return: void */ public static void refreshJsapiTicket(WechatVerificationBean wechatVerification/*, IWeChatVerificationService weChatVerificationService*/) { String jsapiTicket = JsapiTicketUtil.getJSApiTicket(); wechatVerification.setParameterValue(jsapiTicket); //7200后面可能会变化,此处暂时没有做这块设定,到时候用系统参数配置要缓存的时长,即可实现变化的配置 //正式环境缓存时长应该是7200s,也就是120分钟,但是考虑服务器时间差等因素,缓存60分钟即可 wechatVerification.setCertificationTime(String.valueOf(DateUtil.offsetHour(DateUtil.parse(DateUtil.now()), 60))); log.info("获取jsapiTicket成功:{}", jsapiTicket); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); wechatVerification.setCreateTime(simpleDateFormat.format(new Date())); // weChatVerificationService.megerWechatVerification(wechatVerification); } }
Common01ScanController类放两个静态变量
public static Map<String, WechatVerificationBean> map = new HashMap<>();
public static ThreadLocal<ConstantsJsSdkBean> tl = new ThreadLocal<>();
业务代码
private static String create_nonce_str() throws Exception { return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32); } private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); }
写个发方法把下边一串代码放进去就可用了 最后把jssdkBean返回给前端就能用了
//获取jsapi_ticket 组装出餐数据 appid 生成签名的时间戳 生成签名的随机串 签名 需要使用的JS接口列表 String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String string1; String signature = ""; JSSDKBean jssdkBean = new JSSDKBean(); String url = request.getParameter("url"); //jsapi_ticket WechatVerificationBean wechatVerificationBean = null; if(map.containsKey("jsapi_ticket")){ WechatVerificationBean wechatVerification = map.get("jsapi_ticket"); wechatVerificationBean = WxVerificationUtil.getWxVerification("jsapi_ticket",wechatVerification); }else{ WechatVerificationBean wechatVerification = new WechatVerificationBean(); wechatVerification.setCertificationTime(DateUtil.now()); wechatVerificationBean = WxVerificationUtil.getWxVerification("jsapi_ticket",wechatVerification); map.put("jsapi_ticket",wechatVerificationBean); } //access_token WechatVerificationBean access_token = null; if(map.containsKey("access_token")){ WechatVerificationBean wechatVerification = map.get("access_token"); access_token = WxVerificationUtil.getWxVerification("access_token",wechatVerification); }else{ WechatVerificationBean wechatVerification = new WechatVerificationBean(); wechatVerification.setCertificationTime(DateUtil.now()); access_token = WxVerificationUtil.getWxVerification("access_token",wechatVerification); map.put("access_token",access_token); } //注意这里参数名必须全部小写,且必须有序 string1 = "jsapi_ticket=" + wechatVerificationBean.getParameterValue() + "&noncestr=" + nonce_str+ "×tamp=" + timestamp + "&url=" + url; signature = SHA1.encode(string1); jssdkBean.setUrl(url); jssdkBean.setAppId(constantsJsSdkBean.getAppId()); jssdkBean.setJsapi_ticket(wechatVerificationBean.getParameterValue()); jssdkBean.setNoncestr(nonce_str); jssdkBean.setSignature(signature); jssdkBean.setTimestamp(timestamp); // SHA1.encode(string1); jssdkBean.setAccess_token(access_token.getParameterValue());