本文共 13234 字,大约阅读时间需要 44 分钟。
1.wechat.appId以及wechat.accessToken从配置文件读取
2.getTicketCache方法以及getAccessTokenCache方法为了缓存jsapi_ticket跟access_token写的,直接缓存在系统中了,可以考虑换成保存到数据库 3.WechatTicket.java配合上面缓存方法用的,改用数据库存取的话可不用此类控制层代码:
WechatConfigController.java
package com.icafe8.activity.service.web;import java.util.Arrays;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.SortedMap;import java.util.TreeMap;import java.util.UUID;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.codec.digest.DigestUtils;import org.apache.commons.lang.StringUtils;import org.apache.log4j.Logger;import org.json.JSONObject;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.context.request.WebRequest;import com.icafe8.activity.UserContext;import com.icafe8.activity.common.util.PropertiesUtil;import com.icafe8.activity.service.util.DloadImgUtil;import com.icafe8.activity.service.util.Sha1;import com.icafe8.activity.service.util.WeiXinUtil;@Controllerpublic class WechatConfigController { private Logger logger = Logger.getLogger(WechatConfigController.class); /** * 微信验证接口 **/ @RequestMapping(value = "/weixin", method = { RequestMethod.POST, RequestMethod.GET }, headers = "Accept=application/xml") @ResponseBody public String doService(HttpServletRequest servletRequest, WebRequest webRequest, HttpServletResponse response, @RequestBody(required = false) String body, Model model) { logger.info("微信通知:"+servletRequest.getQueryString()); String signature = servletRequest.getParameter("signature"); String timestamp = servletRequest.getParameter("timestamp"); String nonce = servletRequest.getParameter("nonce"); String echostr = servletRequest.getParameter("echostr"); // 加密/校验流程: // 1. 将token、timestamp、nonce三个参数进行字典序排序 // 2. 将三个参数字符串拼接成一个字符串进行sha1加密 // 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 String token = "activity"; String[] arrStr = { token, timestamp, nonce }; Arrays.sort(arrStr); StringBuilder signBuilder = new StringBuilder().append(arrStr[0]).append(arrStr[1]).append(arrStr[2]); if (DigestUtils.shaHex(signBuilder.toString()).equals(signature)) { if (StringUtils.isNotBlank(body)) { } } return echostr; } /** * 微信配置接口 **/ @SuppressWarnings({"rawtypes" }) @RequestMapping(value = "/wechatConfig", produces = "application/json; charset=utf-8") public @ResponseBody Object getNowPersonInfo(ServletRequest request,ServletResponse response) throws Exception { response.setCharacterEncoding("UTF-8"); JSONObject jsonObject = new JSONObject(); //创建有序的Map用于创建签名串 SortedMapparams = new TreeMap (); try { //获取appId String appId = PropertiesUtil.getProperty("wechat.appId"); //获取页面路径(前端获取时采用location.href.split('#')[0]获取url) String url = request.getParameter("url"); //获取access_token //String access_token = new WeiXinUtil().getAccessToken(); String access_token = new WeiXinUtil().getAccessTokenCache(); //获取ticket String jsapi_ticket = new WeiXinUtil().getTicketCache(access_token); //获取Unix时间戳(java时间戳为13位,所以要截取最后3位,保留前10位) String timeStamp = String.valueOf(System.currentTimeMillis()).substring(0, 10); params.put("jsapi_ticket", jsapi_ticket); params.put("timestamp", timeStamp); UUID uuid = UUID.randomUUID(); params.put("noncestr", uuid.toString()); params.put("url", url); //签名 StringBuilder sb = new StringBuilder(); Set set = params.entrySet(); Iterator iterator=set.iterator(); while (iterator.hasNext()){ Map.Entry mapentry = (Map.Entry) iterator.next(); sb.append(mapentry.getKey()).append("=").append(mapentry.getValue()).append("&"); } String signatureParams = sb.toString().substring(0,sb.toString().length()-1); String signature = new Sha1().getDigestOfString(signatureParams.getBytes()).toLowerCase(); //得到签名再组装到Map里 params.put("signature", signature); //传入对应的appId params.put("appId", appId); //组装完毕,回传 jsonObject = new JSONObject(params); } catch (Exception e) { logger.error("调用通过config接口注入权限验证配置失败",e); } return jsonObject.toString(); }}
WeiXinUtil.java
package com.icafe8.activity.service.util;import java.util.HashMap;import java.util.Map;import org.apache.log4j.Logger;import org.json.JSONObject;import com.icafe8.activity.common.util.CommonUtil;import com.icafe8.activity.common.util.PropertiesUtil;public class WeiXinUtil { private Logger logger = Logger.getLogger(WeiXinUtil.class); public static String URL_GET_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/get"; private static MapWechatTicket.javaticketMap = new HashMap (); public String getAccessToken(){ String access_token = ""; try { // 拼接请求地址 String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; requestUrl = requestUrl.replace("APPID",PropertiesUtil.getProperty("wechat.appId")); requestUrl = requestUrl.replace("APPSECRET",PropertiesUtil.getProperty("wechat.accessToken")); // 获取网页授权凭证 JSONObject jsonObject = CommonUtil.getHttpsRequest(requestUrl); if (null != jsonObject) { try { access_token = jsonObject.getString("access_token"); } catch (Exception e) { int errorCode = jsonObject.getInt("errcode"); String errorMsg = jsonObject.getString("errmsg"); logger.error("获取access_token失败 errcode:" + errorCode + ",errmsg:" + errorMsg); } } } catch (Exception e) { logger.error("获取access_token异常"); } return access_token; } public String getTicket(String access_token) throws Exception { String ticket = ""; // 拼接请求地址 String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; requestUrl = requestUrl.replace("ACCESS_TOKEN", access_token); // 获取网页授权凭证 JSONObject jsonObject = CommonUtil.getHttpsRequest(requestUrl); if (null != jsonObject) { try { ticket = jsonObject.getString("ticket"); } catch (Exception e) { int errorCode = jsonObject.getInt("errcode"); String errorMsg = jsonObject.getString("errmsg"); logger.error("获取jsapi_ticket失败 errcode:" + errorCode + ",errmsg:" + errorMsg); } } return ticket; } /** * 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。 * 由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务。 * jsapi_ticket的有效期为7200秒,通过access_token来获取。 * 开发者必须在自己的服务全局缓存jsapi_ticket * */ public String getTicketCache(String access_token){ String jsapi_ticket = ""; try { WechatTicket ticket = ticketMap.get("ticket"); String timestamp = "0"; if(null != ticket){ timestamp = ticketMap.get("ticket").getTimestamp(); } //判断是否有效 Long now = Long.parseLong(String.valueOf(System.currentTimeMillis()).substring(0, 10))-Long.parseLong(timestamp); if(now > 3600 ){ //无效重新获取并写入 jsapi_ticket = new WeiXinUtil().getTicket(access_token); WechatTicket wechatTicket = new WechatTicket(); wechatTicket.setTicket(jsapi_ticket); wechatTicket.setTimestamp(String.valueOf(System.currentTimeMillis()).substring(0, 10)); ticketMap.put("ticket", wechatTicket); logger.info("缓存中不存在jsapi_ticket或jsapi_ticket已经失效,重新请求微信获取ticket:"+jsapi_ticket); }else{ jsapi_ticket = ticketMap.get("ticket").getTicket(); logger.info("缓存中存在jsapi_ticket且不过期,jsapi_ticket:"+jsapi_ticket); } } catch (Exception e) { logger.error("获取缓存jsapi_ticket失败"); } return jsapi_ticket; } public String getAccessTokenCache() { String access_token = ""; try { WechatTicket token = ticketMap.get("access_token"); String timestamp = "0"; if(null != token){ timestamp = ticketMap.get("access_token").getTimestamp(); } //判断是否有效 Long now = Long.parseLong(String.valueOf(System.currentTimeMillis()).substring(0, 10))-Long.parseLong(timestamp); if(now > 3600 ){ //无效重新获取并写入 access_token = new WeiXinUtil().getAccessToken(); WechatTicket wechatTicket = new WechatTicket(); wechatTicket.setTicket(access_token); wechatTicket.setTimestamp(String.valueOf(System.currentTimeMillis()).substring(0, 10)); ticketMap.put("access_token", wechatTicket); logger.info("缓存中不存在token或tonken已经失效,重新请求微信获取token:"+access_token); }else{ access_token = ticketMap.get("access_token").getTicket(); logger.info("缓存中存在token且不过期,token:"+access_token); } } catch (Exception e) { logger.error("获取缓存access_token失败"); } return access_token; }}
package com.icafe8.activity.service.util;public class WechatTicket { private String ticket; private String timestamp; public String getTicket() { return ticket; } public void setTicket(String ticket) { this.ticket = ticket; } public String getTimestamp() { return timestamp; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; }}CommonUtil.java
package com.icafe8.activity.common.util;import java.io.IOException;import org.apache.http.HttpEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import org.apache.log4j.Logger;import org.json.JSONObject;public class CommonUtil { private static Logger logger = Logger.getLogger(CommonUtil.class); /** * 发送 get请求 */ public static JSONObject getHttpsRequest(String requestUrl) { JSONObject myJsonObject = new JSONObject(); // 创建默认的httpClient实例 CloseableHttpClient httpClient = getHttpClient(); try { // 用get方法发送http请求 HttpGet get = new HttpGet(requestUrl); logger.info("执行get请求:...." + get.getURI()); CloseableHttpResponse httpResponse = null; // 发送get请求 httpResponse = httpClient.execute(get); try { // response实体 HttpEntity entity = httpResponse.getEntity(); if (null != entity) { String status = httpResponse.getStatusLine().toString(); String response = EntityUtils.toString(entity); logger.info("响应状态码:" + status +",响应内容:" + response); myJsonObject = new JSONObject(response); } } finally { httpResponse.close(); } } catch (Exception e) { e.printStackTrace(); } finally { try { closeHttpClient(httpClient); } catch (IOException e) { e.printStackTrace(); } } return myJsonObject; } private static CloseableHttpClient getHttpClient() { return HttpClients.createDefault(); } private static void closeHttpClient(CloseableHttpClient client) throws IOException { if (client != null) { client.close(); } }}前端js调用.js
function load_config(){ $.ajax({ url: 'wechatConfig.do?url=' + location.href.split('#')[0], type: "GET", contentType: "application/json; charset=utf-8", success: function(res) { initWeChat(res); } });}var initWeChat = function(res) { wx.config({ debug: false, appId: res.appId, timestamp: res.timestamp, nonceStr: res.noncestr, signature: res.signature, jsApiList: ['chooseImage', 'uploadImage', 'downloadImage', 'onMenuShareTimeline','previewImage'] }); wx.ready(function() { wx.checkJsApi({ jsApiList: ['chooseImage', 'onMenuShareTimeline', 'downloadImage', 'uploadImage','previewImage'], success: function(res) {}, fail: function(res) { alert(JSON.stringify(res)); } }); var localUrl='http://weichat2.swjoy.com/activity/'; $("#btnSaveFile").click(function(){ //console.log(localUrl+$("#pic-box").attr("src")); var imagePaths=[]; imagePaths.push(localUrl+$("#pic-box").attr("src")); console.log(imagePaths) wx.previewImage({ urls:imagePaths, current: localUrl+$("#pic-box").attr("src") }) //window.location.href=$("#pic-box").attr("src"); }) wx.onMenuShareTimeline({ title: getShareTimelineTitle(), // 分享标题 link: localUrl+'login.jsp', // 分享链接 imgUrl: localUrl+'/css/images/icon-icafe.jpg', // 分享图标 success: function() { // 用户确认分享后执行的回调函数 }, cancel: function() { // 用户取消分享后执行的回调函数 } }); }); function getShareTimelineTitle(){ return '财富机密档案,99%的人不知道...'; }}
转载地址:http://pihji.baihongyu.com/