原文:http://blog.csdn.net/wangjuan_01/article/details/51919551
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
请注意,如果你的页面启用了https,务必引入 https://res.wx.qq.com/open/js/jweixin-1.0.0.js ,否则将无法在iOS9.0以上系统中成功使用JSSDK
如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名,见附录1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 });
步骤四:通过ready接口处理成功验证
wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 });
步骤五:通过error接口处理失败验证
wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 });
步骤六:具体接口调用,调用之前要获取接口调用凭据,具体如下:
1.配置文件 application-common.properties 配置一些接口常量信息
- #u5FAEu4FE1AppID
- AppID=wx0a5aabbccddees
- #u5FAEu4FE1AppSecret
- AppSecret=f1ec0d65d104589ds0opke907dslsjeln09
2.工具类ConfigHelper,读取配置文件:
- package com.hengxin.qianee.commons;
- import java.util.ResourceBundle;
- /**
- * 读取配置文件
- * @author hzg
- *
- */
- public class ConfigHelper {
- private static Object lock = new Object();
- private static ConfigHelper config = null;
- private static ResourceBundle rb = null;
- private ConfigHelper(String configFileName) {
- rb = ResourceBundle.getBundle(configFileName);
- }
- public static ConfigHelper getInstance(String configFileName) {
- synchronized(lock) {
- if(null == config) {
- config = new ConfigHelper(configFileName);
- }
- }
- return (config);
- }
- public String getValue(String key) {
- return (rb.getString(key));
- }
- }
3.获取签名信息
- package com.hengxin.qianee.talent.wechat.utils;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.UUID;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.springframework.beans.factory.annotation.Autowired;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.hengxin.qianee.cache.impl.MyCache;
- import com.hengxin.qianee.commons.ConfigHelper;
- import com.hengxin.qianee.service.thirdparty.pay.llpay.conn.CustomHttpClient;
- public class WechatSignUtil {
- @Autowired
- MyCache cache;
- public static JSONObject sendGetRequest(String url){
- HttpClient httpClient = CustomHttpClient.GetHttpClient();
- HttpGet get = new HttpGet(url);
- get.setHeader("Content-Type",
- "application/x-www-form-urlencoded;charset=utf-8");
- BufferedReader br = null;
- try {
- // 发送请求,接收响应
- HttpResponse resp = httpClient.execute(get);
- int ret = resp.getStatusLine().getStatusCode();
- if(ret == HttpStatus.SC_OK){
- // 响应分析
- HttpEntity entity = resp.getEntity();
- br = new BufferedReader(new InputStreamReader(
- entity.getContent(), "UTF-8"));
- StringBuffer responseString = new StringBuffer();
- String str = br.readLine();
- while (str != null) {
- responseString.append(str);
- str = br.readLine();
- }
- return JSON.parseObject(responseString.toString());
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally {
- if (br != null) {
- try {
- br.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
- return new JSONObject();
- }
- /**
- * 获取签名信息
- * @return 返回签名等
- */
- public Map<String,String> getWechatSign(HttpServletRequest request,MyCache cache) throws UnsupportedEncodingException{
- String appid = ConfigHelper.getInstance("config").getValue("AppID");
- String appSecret = ConfigHelper.getInstance("config").getValue("AppSecret");
- String url_Template_GetAccessToken ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
- String url_Template_GetAccessTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
- String accessToken = cache.getString("wechatAccessToken");
- if(accessToken == null){
- //获取token
- String url_GetAccessToken = String.format(url_Template_GetAccessToken, appid,appSecret);
- JSONObject accessTokenMap = WechatSignUtil.sendGetRequest(url_GetAccessToken);
- accessToken = accessTokenMap.getString("access_token");
- cache.setString("wechatAccessToken", 6000, accessToken);
- }
- String accessTicket = cache.getString("wechatAccessTicket");
- if(accessTicket == null){
- //获取ticket
- String url_GetAccessTicket = String.format(url_Template_GetAccessTicket, accessToken);
- JSONObject url_GetAccessTicketMap = WechatSignUtil.sendGetRequest(url_GetAccessTicket);
- accessTicket = url_GetAccessTicketMap.getString("ticket");
- cache.setString("wechatAccessTicket", 6000, accessTicket);
- }
- // 时间戳
- Long timeStamp = new Date().getTime()/1000;
- String url = request.getRequestURL().toString();
- //随机字串
- String noncestr = UUID.randomUUID().toString();
- //签名
- String signature = getSignature(noncestr,accessTicket,url,timeStamp);
- Map<String,String> result = new HashMap<String,String>();
- result.put("appId", appid);
- result.put("timestamp", timeStamp.toString());
- result.put("nonceStr", noncestr);
- result.put("signature", signature);
- return result;
- }
- /**
- * 生成签名
- * @param nonceStr 随机字串
- * @param jsapi_ticket 票据
- * @param url
- * @param timestamp 时间戳
- * @return
- */
- private String getSignature(String nonceStr,String jsapi_ticket,String url,Long timestamp){
- String template = "jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s";
- String result = String.format(template, jsapi_ticket,nonceStr,timestamp,url);
- return org.apache.commons.codec.digest.DigestUtils.shaHex(result);
- }
- }
总结:先配置好域名,先根据appid和appSecret拼成的串发送请求获取到一个JSONObject对象,通过该对象调用getString("access_token")方法取到token;
根据token拼成的url发送一个http get请求得到JSONObject对象,通过调用该对象的.getString("ticket")方法得到ticket
根据时间戳、随机串、当然访问的url和ticket生产签名,也就是接口调用的凭据。最后jsp页面调用如下:
- <script type="text/javascript"
- src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
- <style type="text/css">
- </style>
- <script type="text/javascript">
- wx.config({
- debug : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
- appId : "${appId}", // 必填,公众号的唯一标识
- timestamp : "${timestamp}", // 必填,生成签名的时间戳
- nonceStr : "${nonceStr}", // 必填,生成签名的随机串
- signature : "${signature}",// 必填,签名,见附录1
- jsApiList : [ 'onMenuShareTimeline', 'onMenuShareAppMessage',
- 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone' ]
- });
- var obj = {
- title : '标题',
- desc : '欢迎关注!',
- link : 'http://m.test.com',
- imgUrl : 'https://qianee-official.oss-cn-beijing.aliyuncs.com/data/2016-05-21%2Fe382d374-f3c5-45bb-b8cedlsjelnge',
- };
- wx.ready(function(){
- wx.onMenuShareAppMessage(obj);
- // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
- wx.onMenuShareTimeline(obj);
- // 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口
- wx.onMenuShareQQ(obj);
- // 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口
- wx.onMenuShareWeibo(obj);
- });