微信公眾號網頁分享功能開發總結
阿新 • • 發佈:2019-02-18
最近要做一個微信公眾號頁面分享功能,其中遇到了不少問題,別的先不多說了,直接上程式碼。
Controller層:
/** * *<pre> *<b> 跳轉二維碼頁面 .</b> *<b>Description:</b> * *<b>Author:</b> chendy *<b>Date:</b> 2018/04/25 上午9:46:14 *@param session *@return *</pre> */ @RequestMapping(value="//personerErweima") public ModelAndView goErWeiMa(HttpSession session,HttpServletRequest request){ ModelAndView modelAndView = new ModelAndView(); try { UserInfoVo user = userInfoService.showUserinfoByCon(retrievalCurrentUserInfo(session).getLogId()); modelAndView.addObject("user", user); modelAndView.setViewName("/wap/userinfo/erweima");//載入頁面的一些資料資訊 //分享 String url = "/escq/wap/userinfo/personerErweima.html"; //當前頁面的路徑 String domainAddr = "http://vm3kgx.natappfree.cc"; //域名 String fenxurl=domainAddr+"/escq/wap/userinfo/logInfo/jumpJdjerweima.html"; //要分享的路徑(分享出去的連結) Map<String, String> params=HttpXmlClient.getShare(request,url);//獲取簽名 request.setAttribute("params", params); request.setAttribute("fenxurl", fenxurl); //分享結束 } catch (Exception e) { modelAndView.setViewName("wap/userinfo/login"); } return modelAndView; }
獲取簽名:
public class HttpXmlClient { @SuppressWarnings("unchecked") public static String getToken(){//獲取access_token String access_token = ""; String grant_type = "client_credential";//獲取access_token填寫client_credential String AppId="";//第三方使用者唯一憑證 測試號 String secret="";//第三方使用者唯一憑證金鑰,即appsecret 測試號 //這個url連結地址和引數皆不能變 String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+AppId+"&secret="+secret; try { URL urlGet = new URL(url); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); http.setRequestMethod("GET"); // 必須是get方式請求 http.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 連線超時30秒 System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 讀取超時30秒 http.connect(); InputStream is = http.getInputStream(); int size = is.available(); byte[] jsonBytes = new byte[size]; is.read(jsonBytes); String message = new String(jsonBytes, "UTF-8"); Map<String, String> map = (Map<String, String>) JSON.parse(message); // JSONObject demoJson = JSONObject.fromObject(message); // System.out.println("JSON字串:"+demoJson); access_token = map.get("access_token"); is.close(); } catch (Exception e) { e.printStackTrace(); } return access_token; } @SuppressWarnings("unchecked") public static String getTicket(String access_token) { String ticket = null; String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";//這個url連結和引數不能變 try { URL urlGet = new URL(url); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); http.setRequestMethod("GET"); // 必須是get方式請求 http.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 連線超時30秒 System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 讀取超時30秒 http.connect(); InputStream is = http.getInputStream(); int size = is.available(); byte[] jsonBytes = new byte[size]; is.read(jsonBytes); String message = new String(jsonBytes, "UTF-8"); Map<String, String> map = (Map<String, String>) JSON.parse(message); // JSONObject demoJson = JSONObject.fromObject(message); // System.out.println("JSON字串:"+demoJson); ticket = map.get("ticket"); is.close(); } catch (Exception e) { e.printStackTrace(); } return ticket; } public static String SHA1(String decript) { try { MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); digest.update(decript.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 位元組陣列轉換為 十六進位制 數 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static String CreateNoncestr() { String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String res = ""; for (int i = 0; i < 16; i++) { Random rd = new Random(); res += chars.charAt(rd.nextInt(chars.length() - 1)); } return res; } public static Map<String,String> getShare(HttpServletRequest request,String url){ //微信分享授權開始 String appId ="" ;//取專案中配置的公眾號id 測試號 String domainAddr = "http://vm3kgx.natappfree.cc";//專案中配置的網站的域名 測試域名 String str = request.getQueryString(); Map<String, String> map = new HashMap<String, String>(); map.put("appid", appId); // String url="http://vm3kgx.natappfree.cc/escq/wap/userinfo/personerErweima.html"; url=domainAddr+url; map.put("url", url); String jsapi_token=SingletonUtil.getJsapiTicket(SingletonUtil.getAccessToken()); //生成簽名 SortedMap<Object,Object> params = new TreeMap<Object,Object>(); params.put("timestamp", Long.toString(new Date().getTime()/1000)); params.put("noncestr", HttpXmlClient.CreateNoncestr()); params.put("jsapi_ticket",jsapi_token); System.out.println("列印資料:"+jsapi_token+" url: "+map.get("url")); params.put("url",map.get("url"));//url地址 StringBuffer sb = new StringBuffer(); Set es = params.entrySet(); Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = entry.getValue(); sb.append(k + "=" + v + "&"); } String signStr = sb.toString().substring(0, sb.toString().length()-1); String sign = HttpXmlClient.SHA1(signStr);//簽名 Map<String, String> result = new HashMap<String,String>(); result.put("timestamp",(String)params.get("timestamp")); result.put("noncestr", (String)params.get("noncestr")); result.put("signature", sign); result.put("appId",map.get("appid")); System.out.println("列印資料:"+result); return result; } }
SingletonUtil:
import java.util.Date; import java.util.Map; public class SingletonUtil { //快取授權資訊 public static String getAccessToken() { String result = ""; SingletonAccessToken singleton = SingletonAccessToken.getInstance(); Map<String, String> map = singleton.getMap(); String time = map.get("time"); String accessToken = map.get("access_token"); Long nowDate = new Date().getTime(); if (accessToken != null && time != null && nowDate - Long.parseLong(time) < 7000 * 1000) { result = accessToken; } else { String access_token=HttpXmlClient.getToken(); map.put("time", nowDate + ""); map.put("access_token", access_token); result = access_token; } return result; } public static String getJsapiTicket(String accessToken) { String result = ""; SingletonJsapiTicket singleton = SingletonJsapiTicket.getInstance(); Map<String, String> map = singleton.getMap(); String time = map.get("time"); String jsapiTicket = map.get("jsapi_ticket"); Long nowDate = new Date().getTime(); if (jsapiTicket != null && time != null && nowDate - Long.parseLong(time) < 7000 * 1000) { result = jsapiTicket; } else { String jsapi_ticket=HttpXmlClient.getTicket(accessToken); map.put("time", nowDate + ""); map.put("jsapi_ticket", jsapi_ticket); result = jsapi_ticket; } return result; } }
Token單例:
import java.util.HashMap;
import java.util.Map;
/**
*
* <pre>
* <b> token的單例.</b>
* <b>Description:</b>
*
* <b>Author:</b> yanhongyu
* <b>Date:</b> 2017-6-23上午9:34:38
* <b>Changelog:</b>
* ----------------------------------------------------------------------------
* Ver Date Detail
* ----------------------------------------------------------------------------
* 1.0 2017-6-23上午9:34:38 new file.
* </pre>
*/
public class SingletonAccessToken {
//快取accessToken 和一個 時間
private Map<String, String> map = new HashMap<String,String>();
private SingletonAccessToken() {
}
private static SingletonAccessToken single = null;
public static SingletonAccessToken getInstance() {
if (single == null) {
single = new SingletonAccessToken();
}
return single;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public static SingletonAccessToken getSingle() {
return single;
}
public static void setSingle(SingletonAccessToken single) {
SingletonAccessToken.single = single;
}
}
Ticket單例:
import java.util.HashMap;
import java.util.Map;
/**
*
* <pre>
* <b> ticket的單例.</b>
* <b>Description:</b>
*
* <b>Author:</b> yanhongyu
* <b>Date:</b> 2017-6-23上午9:34:38
* <b>Changelog:</b>
* ----------------------------------------------------------------------------
* Ver Date Detail
* ----------------------------------------------------------------------------
* 1.0 2017-6-23上午9:34:38 new file.
* </pre>
*/
public class SingletonJsapiTicket {
//快取jsapi_ticket 和一個 時間
private Map<String, String> map = new HashMap<String,String>();
private SingletonJsapiTicket() {
}
private static SingletonJsapiTicket single = null;
public static SingletonJsapiTicket getInstance() {
if (single == null) {
single = new SingletonJsapiTicket();
}
return single;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public static SingletonJsapiTicket getSingle() {
return single;
}
public static void setSingle(SingletonJsapiTicket single) {
SingletonJsapiTicket.single = single;
}
}
jsp頁面:
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<%--通過config介面注入許可權驗證配置--%>
<script>
wx.config({
debug: false,
appId: '${params.appId}',
timestamp: '${params.timestamp}',
nonceStr: '${params.noncestr}',
signature:'${params.signature}',
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.ready(function(){
wx.checkJsApi({
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.checkJsApi({
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
/*分享到朋友圈*/
wx.onMenuShareTimeline({
title: '', // 分享標題
desc: '', // 分享描述
link: '${fenxurl}', // 分享連結
imgUrl: '', // 分享圖示
success: function () {
// 使用者確認分享後執行的回撥函式
},
cancel: function () {
// 使用者取消分享後執行的回撥函式
}
});
/*分享給朋友*/
wx.onMenuShareAppMessage({
title: '近', // 分享標題
desc: '', // 分享描述
link: '${fenxurl}', // 分享連結
imgUrl: '', // 分享圖示
type: 'link', // 分享型別,music、video或link,不填預設為link
dataUrl: '', // 如果type是music或video,則要提供資料鏈接,預設為空
success: function () {
// 使用者確認分享後執行的回撥函式
alert("感謝您的分享");
},
cancel: function () {
// 使用者取消分享後執行的回撥函式
alert('您已取消分享');
}
});
wx.onMenuShareQQ({
title: '', // 分享標題
desc: '', // 分享描述
link: '${fenxurl}', // 分享連結
imgUrl: '', // 分享圖示
success: function () {
// 使用者確認分享後執行的回撥函式
},
cancel: function () {
// 使用者取消分享後執行的回撥函式
}
});
wx.onMenuShareWeibo({
title: '', // 分享標題
desc: '', // 分享描述
link: '${fenxurl}', // 分享連結
imgUrl: '', // 分享圖示
success: function () {
// 使用者確認分享後執行的回撥函式
},
cancel: function () {
// 使用者取消分享後執行的回撥函式
}
});
wx.onMenuShareQZone({
title: '', // 分享標題
desc: '', // 分享描述
link: '${fenxurl}', // 分享連結
imgUrl: '', // 分享圖示
success: function () {
// 使用者確認分享後執行的回撥函式
},
cancel: function () {
// 使用者取消分享後執行的回撥函式
}
});
});
</script>
完成以上步驟,完成微信公眾號網頁分享功能開發,最後上圖。
注意:
1、簽名時的url是當前網頁的路徑,一定要一模一樣不然會導致簽名無效。
2、分享頁面的域名要是安全域名下的路徑
3、分享路徑和分享圖片路徑一定要正確,如果是404連結會導致分享失敗,查程式碼時會發現都沒問題,然而就不成功。