步驟一:綁定域名
先登錄微信公衆平臺進入“公衆號設置”的“功能設置”裏填寫“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 配置一些接口常量信息
#\u5FAE\u4FE1AppID
AppID=wx0a5aabbccddees
#\u5FAE\u4FE1AppSecret
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);
});