项目存放accessToken 皆是一redis存储
1. 获得Access Token
并且获取jsapi_ticket
accessToken 存在有效期 所以,用定时任务 定时刷新
WeChatServiceImpl
一下几个方法来处理:
/** * 刷新AccessToken * 仅在 接口返回token失效时 * @return */ @Override public boolean flushWeChatAccessToken() throws Exception{ // 获取AccessToken String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; String appid = PropertiesReader.readString("weChat","server_appId"); String secret = PropertiesReader.readString("weChat","server_appSecret"); requestUrl = String.format(requestUrl, appid, secret); JSONObject accessTokenObject = HttpClientUtil.getToHttps(requestUrl); String accessToken = accessTokenObject.getString("access_token"); int expireTime = accessTokenObject.getInteger("expires_in"); setAccessToken(Const.WEIXINACCESSTOKEN,accessToken,expireTime); // 获取jsticket String jsticketRequestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"; jsticketRequestUrl = String.format(jsticketRequestUrl, accessToken); JSONObject jsticketObject = HttpClientUtil.getToHttps(jsticketRequestUrl); String ticket = jsticketObject.getString("ticket"); int ticketExpireTime = jsticketObject.getInteger("expires_in"); String result = setAccessToken(Const.JSACCESSTOKEN,ticket,ticketExpireTime); return true; }
/** * 通过Redis 获取AccessToken * @return * @throws IOException */ public String getAccessToken(String key) throws IOException{ JedisCluster jedisCluster = redisClusterFactory.getJedisCluster(); String reaultStr = ""; boolean result = jedisCluster.exists(key); if (result) { reaultStr = jedisCluster.get(key); } return reaultStr; } /** * 通过Redis 获取AccessToken * @return * @throws IOException */ public String setAccessToken(String key, String val ,int millions) throws IOException{ JedisCluster jedisCluster = redisClusterFactory.getJedisCluster(); String reaultStr = jedisCluster.setex(key, millions , val); return reaultStr; }2验证签名
package com.yxb.utils.encrypt; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * @Description: 用于微信签名 * @date 2016/12/9 12:53 */ public class WeChatSHA { /** * 微信SHA1签名 * @return */ public static String Sign(String ticket, String noncestr, String timestamp, String url) { String canSign = "jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s"; canSign = String.format(canSign, ticket, noncestr, timestamp, url); try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可 digest.update(canSign.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexStr = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexStr.append(0); } hexStr.append(shaHex); } return hexStr.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(WeChatSHA.Sign("123","122","221","222")); } }
3,返回签名的接口
/** * 微信分享接口 * @return */ @PostMapping("/wechat/weixinshare") @ResponseBody public ResponseModel<Map<String,Object>> weChatShare(String url){ Map<String,Object> result = new HashedMap(); try{ String noncestr = UUID.randomUUID().toString(); String timestamp = new Date().getTime()+""; result.put("appId", PropertiesReader.readString("weChat","server_appId")); result.put("timestamp", timestamp); result.put("nonceStr", noncestr); String ticket = weChatService.getAccessToken(Const.JSACCESSTOKEN) ; result.put("signature", WeChatSHA.Sign(ticket, noncestr, timestamp,url)); return new ResponseModel(ErrorEnum.SUCCESS.getResCode() , ErrorEnum.SUCCESS.getMsg(), result); } catch ( Exception e ){ e.printStackTrace(); } return new ResponseModel(ErrorEnum.WECHAT_SHAREFAIL.getResCode() , ErrorEnum.WECHAT_SHAREFAIL.getMsg(), result); }4,页面ajax 加载
$(function(){ // 拉取分享接口 $.ajax({ url:"/wechat/wechat/weixinshare", type:"POST", async:"false", dataType: "json", data: { url:window.location.href }, success:function(data){ console.log(data) if(data.resCode == '00000'){//已经登录 wx.config({ debug: false, appId: data.data.appId, // 必填,公众号的唯一标识 timestamp: data.data.timestamp, // 必填,生成签名的时间戳 nonceStr: data.data.nonceStr, // 必填,生成签名的随机串 signature: data.data.signature,// 必填,签名,见附录1 jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); } }, error:function(){ } }); });5,通过ready接口处理成功验证
wx.ready(function(){ wx.onMenuShareTimeline({ title: '邀请好友双重礼 钟情可“荐”', // 分享标题 link: hosts+'/weixin/detail/publicChannel.html?sharecode='+shareCode, // 分享链接 imgUrl: 'http://'+hosts+'/weixin/detail/img/invite_march_icon.jpg', // 分享图标 success: function () { window.location.href = "/weixin/detail/inviteFriends.html?back=1";//分享成功页面 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); wx.onMenuShareAppMessage({ title: '邀请好友双重礼 钟情可“荐”', desc: '邀请好友平分现金,好友出借持续返现,快来参见吧!', // 分享描述 link: hosts+'/weixin/detail/publicChannel.html?sharecode='+shareCode, // 分享链接 imgUrl: 'http://'+hosts+'/weixin/detail/img/invite_march_icon.jpg', // 分享图标 type: 'link', // 分享类型,music、video或link,不填默认为link dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空 success: function () { window.location.href = "/weixin/detail/inviteFriends.html?back=1" }, cancel: function () { // 用户取消分享后执行的回调函数 } }); });