获取、缓存全局的access_token
/*** 微信全局票据 ---->>>> access_token* @return* @throws ClientProtocolException* @throws IOException*/ public String getBaseAccessToken() throws ClientProtocolException, IOException{ try { String value = redisService.get("WEIXIN_BASE_ACCESS_TOKEN"); if (!StringUtils.isEmpty(value)) {LOGGER.info("Get base access_token from redis is successful.value:{}",value);return value; }else{synchronized (this) { //缓存中没有、或已经失效 String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WX_APPID+"&secret="+ WX_APPSECRET; String rs = apiService.doGet(url);JSONObject obj_content = JSONObject.parseObject(rs); String accessToken = obj_content.getString("access_token"); Integer time = Integer.parseInt(obj_content.getString("expires_in").toString());//写缓存 redisService.set("WEIXIN_BASE_ACCESS_TOKEN", accessToken, time - 3600); LOGGER.info("Set base access_token to redis is successful.parameters time:{},realtime",time,time-3600); return accessToken;} }} catch (Exception e) { LOGGER.error("Get base access_token from redis is error.");}return null; }先从缓存中取key为“WX_BASE_ACCESS_TOKEN” ,如果命中直接返回值,反之通过httpclient发送GET请求调用微信提供的接口获取全局的access_token,同时将取到的值写入缓存。
/*** jsapi_ticket是公众号用于调用微信JS接口的临时票据* @return* @throws IOException * @throws ClientProtocolException */ public String getJsapiTicket() throws ClientProtocolException, IOException{try { String value = redisService.get("WEIXIN_JS_API_TICKET"); if (!StringUtils.isEmpty(value)) {return value; }else{synchronized (this) { //缓存中没有、或已经失效 //获取全局的access_token,唯一票据 String accessToken = getBaseAccessToken(); String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ accessToken +"&type=jsapi"; String rs = apiService.doGet(url); JSONObject obj_content = JSONObject.parseObject(rs); String jsapi_ticket = obj_content.getString("ticket"); Integer time = Integer.parseInt(obj_content.getString("expires_in").toString()); //写缓存 redisService.set("WEIXIN_JS_API_TICKET", jsapi_ticket, time - 3600); return jsapi_ticket;} }} catch (Exception e) { LOGGER.error("Get js_api_ticket from redis is error:{}",e);}return null; }由于获取jsapi_ticket微信有100000次限制,所以必须用上缓存。同理获取access_token,我这里为了保险起见缓存失效时间设置为官方提供的时间再减去一个小时。
/*** 微信分享证书获取* @param * @return signature* @throws IOException */ @RequestMapping(value = "/signature", method = RequestMethod.GET) public @ResponseBody String createSignature(@RequestParam String url) throws IOException{LOGGER.info("RestFul of createSignature parameters url:{}",url);try { String rs = wechatService.createSignature(url); LOGGER.info("RestFul of signature is successful.",rs); return rs;} catch (Exception e) { LOGGER.error("RestFul of signature is error.",e);}return null; }2.Service
/*** 根据jsapi_ticket等参数进行SHA1加密* @param nonceStr 随机字符串* @param timestamp 当前时间戳* @param url 当前页面url*/ public String createSignature(String url) throws ClientProtocolException, IOException{String nonceStr = create_nonce_str();String timestamp = create_timestamp();String signature = "jsapi_ticket="+getJsapiTicket();signature += "&noncestr="+nonceStr;signature += "×tamp="+timestamp;signature += "&url="+url;try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(signature.getBytes("UTF-8")); signature = byteToHex(crypt.digest());} catch (Exception e) { LOGGER.error("Signature for SHA-1 is error:{}",e);}Map<String, String> map = new HashMap<String, String>();map.put("timestamp", timestamp);map.put("nonceStr", nonceStr);map.put("signature", signature);map.put("appid", WX_APPID);return JSON.toJSONString(map, true); } private static String byteToHex(final byte[] hash) {Formatter formatter = new Formatter();for (byte b : hash) { formatter.format("%02x", b);}String result = formatter.toString();formatter.close();return result; }WX_APPID为公众号appid,通过spring@value注解从配置文件获取,这里不细说。
private static String create_nonce_str() {return UUID.randomUUID().toString(); }4.时间格式化
private static String create_timestamp() {return Long.toString(System.currentTimeMillis() / 1000); }到此为止后台全部完成,其实没有太多的解释,仔细读一遍代码,可读性应该还行!
require.config({ urlArgs: "v=20161116" , baseUrl : "/static", paths: {jweixin: "component/jweixin/jweixin-1.0.0",share: "component/wechat/share"//微信分享组件 }})首先通过调用后台接口获取加密字符串,调用微信提供的wx.config()方法
//jsSDK授权 $.signature = function(wx,opts,currentUrl,callback){$.ajax({ data: {url: currentUrl}, type: "GET", url: WX_ROOT + "wechat/signature", success: function (json) {if (json) { var data = JSON.parse(json);wx.config({debug: false,appId: data.appid,timestamp: data.timestamp,nonceStr: data.nonceStr,signature: data.signature,jsApiList: [ "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareWeibo", "onMenuShareQZone"] }); wechatShare.options.isSignature = true; callback && callback(opts,wx);} }}); }建议:开发环境建议开启调式模式,方便打印日志定位问题debug: true
//分享 $.share = function(opts,wx) {var options = {currentUrl: window.location.href.split("#")[0],imgUrl: null,title: "达农保险",desc: null,shareUrl: null }$.extend(true, options, opts || {});//判断是否已经授权if(!wechatShare.options.isSignature){ $.signature(wx,opts,options.currentUrl,$.share)}else{ wx.ready(function(){//分享到朋友圈wx.onMenuShareTimeline({ title: options.title, link: options.shareUrl, imgUrl: options.imgUrl, success: function () {//分享统计,分享来源 1 朋友圈 2分享给朋友 3分享到QQ 4分享到QQ空间}});//分享给朋友wx.onMenuShareAppMessage({ title: options.title, desc: options.desc, link: options.shareUrl, imgUrl: options.imgUrl}); });}}我先确认是否已经配置授权,如果没有授权则调用$.signature()回调函数里传入$.share,有点类似递归调用,当再次回到share方法的时候isSignature已经是true了,则执行wx.ready()方法,再调需要调用的接口,微信开放提供了很多接口给我们,分享只是其中一个。只有想不到的,没有实现不了的....
var ua = navigator.userAgent.toLowerCase(), isWechat = ua.indexOf("micromessenger") != -1;//判断是否为微信浏览器var shareData = { title: ‘测试分享", desc: ‘这里是描述,分享到朋友圈不会显示", link: APP_ROOT + "/base/downloadApp,//分享后打开的链接,必须在配置的安全域名下 imgUrl: PIC_PATH + (self.data.shareListData[0].imgSmall || "/static/img/coupon/getTicPic.png"),//分享后显示的图片 success: function(){setTimeout(function(){ //运营数据统计 },0)//伪异步方式调用 } }//微信浏览器分享加载if(isWechat){ require(["jweixin"],function(wx){ require(["share"],function(){ $.share(shareData,wx); }) })}完整js:https://github.com/helijun/component/blob/master/wechat/share.js