第一部分:微信JS-SDK介紹
微信JS-SDK是微信公眾平台面向網頁開發者提供的基於微信內的網頁開發工具包。
通過使用微信JS-SDK,網頁開發者可借助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優質的網頁體驗。
本次的內容:
實現:分享到朋友圈,qq,qq空間,微信朋友的功能。
基礎接口
判斷當前客戶端版本是否支持指定JS接口
wx.checkJsApi({ jsApiList: ['chooseImage'], // 需要檢測的JS接口列表,所有JS接口列表見附錄2, success: function(res) { // 以鍵值對的形式返回,可用的api值true,不可用為false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} } });
備注:checkJsApi接口是客戶端6.0.2新引入的一個預留接口,第一期開放的接口均可不使用checkJsApi來檢測。
獲取“分享到朋友圈”按鈕點擊狀態及自定義分享內容接口
wx.onMenuShareTimeline({ title: '', // 分享標題 link: '', // 分享鏈接 imgUrl: '', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } });
獲取“分享給朋友”按鈕點擊狀態及自定義分享內容接口
wx.onMenuShareAppMessage({ title: '', // 分享標題 desc: '', // 分享描述 link: '', // 分享鏈接 imgUrl: '', // 分享圖標 type: '', // 分享類型,music、video或link,不填默認為link dataUrl: '', // 如果type是music或video,則要提供數據鏈接,默認為空 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } });
獲取“分享到QQ”按鈕點擊狀態及自定義分享內容接口
wx.onMenuShareQQ({ title: '', // 分享標題 desc: '', // 分享描述 link: '', // 分享鏈接 imgUrl: '', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } });
獲取“分享到騰訊微博”按鈕點擊狀態及自定義分享內容接口
wx.onMenuShareWeibo({ title: '', // 分享標題 desc: '', // 分享描述 link: '', // 分享鏈接 imgUrl: '', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } });
獲取“分享到QQ空間”按鈕點擊狀態及自定義分享內容接口
wx.onMenuShareQZone({ title: '', // 分享標題 desc: '', // 分享描述 link: '', // 分享鏈接 imgUrl: '', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } });
附錄2-所有JS接口列表
版本1.0.0接口
- onMenuShareTimeline
- onMenuShareAppMessage
- onMenuShareQQ
- onMenuShareWeibo
- onMenuShareQZone
附錄3-所有菜單項列表
- 發送給朋友: "menuItem:share:appMessage"
- 分享到朋友圈: "menuItem:share:timeline"
- 分享到QQ: "menuItem:share:qq"
- 分享到Weibo: "menuItem:share:weiboApp"
- 收藏: "menuItem:favorite"
- 分享到FB: "menuItem:share:facebook"
- 分享到 QQ 空間/menuItem:share:QZone
詳細的可以參照微信官方的介紹: 微信JS-SDK說明文檔
第二部分:分享方法的實現。
那么,我們如何來實現這個分享內容呢?
JSSDK使用步驟
步驟一:綁定域名
1. 先登錄微信公眾平台 ,登錄后可在“開發者中心”查看對應的接口權限。
說明了有這個分享的權限。
2. 進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”。
js域名,一般不用http這樣的開頭。
步驟二:引入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 標准模塊加載方法加載
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
步驟三:通過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 });
注意,我這里只是動態獲取,並沒有做緩存,如果有需要的同學,需要做一些緩存。
如何獲取以上的參數呢?

package com.souvc.weixin.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Formatter; import java.util.HashMap; import java.util.Map; import java.util.UUID; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.servlet.http.HttpServletRequest; import net.sf.json.JSONObject; public class WeixinUtil { /** * 方法名:httpRequest</br> * 詳述:發送http請求</br> * 開發人員:souvc </br> * 創建時間:2016-1-5 </br> * @param requestUrl * @param requestMethod * @param outputStr * @return 說明返回值含義 * @throws 說明發生此異常的條件 */ public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { ce.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return jsonObject; } /** * 方法名:getWxConfig</br> * 詳述:獲取微信的配置信息 </br> * 開發人員:souvc </br> * 創建時間:2016-1-5 </br> * @param request * @return 說明返回值含義 * @throws 說明發生此異常的條件 */ public static Map<String, Object> getWxConfig(HttpServletRequest request) { Map<String, Object> ret = new HashMap<String, Object>(); String appId = "xxxx"; // 必填,公眾號的唯一標識 String secret = "xxxx"; String requestUrl = request.getRequestURL().toString(); String access_token = ""; String jsapi_ticket = ""; String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成簽名的時間戳 String nonceStr = UUID.randomUUID().toString(); // 必填,生成簽名的隨機串 String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + secret; JSONObject json = WeixinUtil.httpRequest(url, "GET", null); if (json != null) { //要注意,access_token需要緩存 access_token = json.getString("access_token"); url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi"; json = WeixinUtil.httpRequest(url, "GET", null); if (json != null) { jsapi_ticket = json.getString("ticket"); } } String signature = ""; // 注意這里參數名必須全部小寫,且必須有序 String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "×tamp=" + timestamp + "&url=" + requestUrl; try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(sign.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } ret.put("appId", appId); ret.put("timestamp", timestamp); ret.put("nonceStr", nonceStr); ret.put("signature", signature); return ret; } /** * 方法名:byteToHex</br> * 詳述:字符串加密輔助方法 </br> * 開發人員:souvc </br> * 創建時間:2016-1-5 </br> * @param hash * @return 說明返回值含義 * @throws 說明發生此異常的條件 */ 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; } }
注意:以上需要替換成自己的appid和secret 。
步驟四:通過ready接口處理成功驗證
wx.ready(function(){ // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。 });
根據以上的步驟,我們寫了一個頁面:

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@page language="java" import="com.souvc.weixin.util.WeixinUtil" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>歡迎訪問搜投網 www.souvc.com </title> <% Map<String,Object> ret = new HashMap<String,Object> (); ret=WeixinUtil.getWxConfig(request); request.setAttribute("appId", ret.get("appId")); request.setAttribute("timestamp", ret.get("timestamp")); request.setAttribute("nonceStr", ret.get("nonceStr")); request.setAttribute("signature", ret.get("signature")); %> </head> <body> 歡迎訪問搜投網! </body> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript"> // 微信信息的以及調用的配置 wx.config({ debug: false, appId: '${appId}', timestamp: '${timestamp}', nonceStr: '${nonceStr}', signature: '${signature}', jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] }); wx.ready(function(){ // 獲取“分享到朋友圈”按鈕點擊狀態及自定義分享內容接口 wx.onMenuShareTimeline({ title: '第八篇 :微信公眾平台開發實戰Java版之如何網頁授權獲取用戶基本信息', // 分享標題 link:"http://www.cnblogs.com/liuhongfeng/p/5099149.html", imgUrl: "http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_1442809977405.jpg" // 分享圖標 }); // 獲取“分享給朋友”按鈕點擊狀態及自定義分享內容接口 wx.onMenuShareAppMessage({ title: '第七篇 :微信公眾平台開發實戰Java版之如何獲取微信用戶基本信息', // 分享標題 desc: "第七篇 :微信公眾平台開發實戰Java版之如何獲取微信用戶基本信息", // 分享描述 link:"http://www.cnblogs.com/liuhongfeng/p/5057167.html", imgUrl: "http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_QQ%E5%9B%BE%E7%89%8720151118180508.png", // 分享圖標 type: 'link', // 分享類型,music、video或link,不填默認為link }); //獲取“分享到QQ”按鈕點擊狀態及自定義分享內容接口 wx.onMenuShareQQ({ title: '第六篇 :微信公眾平台開發實戰Java版之如何自定義微信公眾號菜單', // 分享標題 desc: '第六篇 :微信公眾平台開發實戰Java版之如何自定義微信公眾號菜單', // 分享描述 link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享鏈接 imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } }); //獲取“分享到騰訊微博”按鈕點擊狀態及自定義分享內容接口 wx.onMenuShareWeibo({ title: '分享到騰訊微博標題', // 分享標題 desc: '分享到騰訊微博描述', // 分享描述 link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享鏈接 imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } }); //獲取“分享到QQ空間”按鈕點擊狀態及自定義分享內容接口 wx.onMenuShareQZone({ title: '分享到QQ空間標題', // 分享標題 desc: '分享到QQ空間描述', // 分享描述 link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享鏈接 imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享圖標 success: function () { // 用戶確認分享后執行的回調函數 }, cancel: function () { // 用戶取消分享后執行的回調函數 } }); }); </script> </html>
步驟五: 部署到服務器。然后訪問到這個頁面,用微信掃一掃。然后分享到我們設定的接口。
效果如下:
發給微信朋友的效果:
分享到朋友圈的效果:
分享到qq空間的效果:
分享給朋友的效果:
恭喜你,配置成功!!
其他文章關聯:
第一篇:微信公眾平台開發實戰Java版之了解微信公眾平台基礎知識以及資料准備
第二篇 :微信公眾平台開發實戰Java版之開啟開發者模式,接入微信公眾平台開發
第三篇 :微信公眾平台開發實戰Java版之請求消息,響應消息以及事件消息類的封裝
第四篇 :微信公眾平台開發實戰Java版之完成消息接受與相應以及消息的處理
第五篇 :微信公眾平台開發實戰Java版之如何獲取公眾號的access_token以及緩存access_token
第六篇 :微信公眾平台開發實戰Java版之如何自定義微信公眾號菜單
第七篇 :微信公眾平台開發實戰Java版之如何獲取微信用戶基本信息
第八篇 :微信公眾平台開發實戰Java版之如何網頁授權獲取用戶基本信息
第九篇 :微信公眾平台開發實戰Java版之如何實現自定義分享內容