您好,登錄后才能下訂單哦!
本文實例為大家分享了Java微信分享接口開發(fā)的具體代碼,供大家參考,具體內(nèi)容如下
Java微信分享,步驟是
1、根據(jù)當前的url,獲取signature,nonceStr,timestamp 和appId。
2、通過signature,nonceStr,timestamp 和appId來配置微信 wx.config。
3、通過wx.ready實現(xiàn)微信分享功能。
1、html端
引入微信JS-SDK.
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
//分享核心js代碼 $(document).ready(function () { //通過ajax,在頁面加載的時候獲取微信分享接口signature,nonceStr,timestamp 和appId $.ajax({ type: "post", url: "/weixin/share", dataType: "json", data:"url="+window.location.href, success: function (data) { wx.config({ debug: false, appId: data.appId, timestamp: data.timestamp, nonceStr: data.nonceStr, signature: data.signature, jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'hideAllNonBaseMenuItem', 'showMenuItems'] // 功能列表,我們要使用JS-SDK的什么功能 }); wx.ready(function () { // 獲取“分享給朋友”按鈕點擊狀態(tài)及自定義分享內(nèi)容接口 wx.onMenuShareAppMessage({ title: "分享自定義標題", // 分享標題 desc: "分享自定義描述", // 分享描述 link: "http://localhost/weixin/share?openId=1",//分享點擊之后的鏈接 imgUrl:'/images/photo/1.jpg', // 分享圖標 type: 'link', // 分享類型,music、video或link,不填默認為link success: function () { //成功之后的回調 } }); wx.hideAllNonBaseMenuItem(); wx.showMenuItems({ menuList: ['menuItem:share:appMessage', 'menuItem:share:timeline'] // 要隱藏的菜單項,只能隱藏“傳播類”和“保護類”按鈕,所有menu項見附錄3 }); wx.onMenuShareTimeline({ title: "分享自定義標題", // 分享標題 desc: "分享自定義描述", // 分享描述 link: "http://localhost/weixin/share?openId=1",//分享點擊之后的鏈接 imgUrl:'/images/photo/1.jpg', // 分享圖標 type: 'link', // 分享類型,music、video或link,不填默認為link success: function () { //成功之后的回調 } cancel: function () { // 用戶取消分享后執(zhí)行的回調函數(shù) } }); }); wx.error(function (res) { //打印錯誤消息。及把 debug:false,設置為debug:ture就可以直接在網(wǎng)頁上看到彈出的錯誤提示 }); } }) });
2、Java代碼,獲取 signature,nonceStr,timestamp 和appId
@RequestMapping(value = "/share", method = RequestMethod.POST) @ResponseBody public Map<String, Object> share(HttpServletRequest request) { String urlTemp = "http://" + request.getServerName() + request.getContextPath(); String urlpath = "http://" + request.getServerName(); String appUrl = request.getParameter("url"); if (request.getParameter("code") != null) { appUrl += "&code=" + request.getParameter("code"); } if (request.getParameter("state") != null) { appUrl += "&state=" + request.getParameter("state"); } return WxConfigUtil.getSignature(appUrl, ContentValues.APPID, ContentValues.SECRET, urlTemp, urlpath); }
工具類我就把整個貼上來了,其中有些方法是沒有用到的。
getSignature()整個方法是微信分享中的核心方法,用來獲取signature,nonceStr,timestamp 和appId這幾個核心參數(shù)。
package com.blog.common.util; import com.alibaba.fastjson.JSONObject; import com.blog.common.model.Token; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * 公眾平臺通用接口工具類 * * @author james * @date 2015-02-27 */ public class WxConfigUtil { // 獲取access_token的接口地址(GET) 限2000(次/天) public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; // 獲取jsapi_ticket的接口地址(GET) 限2000(次/天) public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; // 緩存添加的時間 public static String cacheAddTime = null; // token,ticket緩存 public static Map<String, Token> TOKEN_TICKET_CACHE = new HashMap<String, Token>(); // token對應的key private static final String TOKEN = "token"; // ticket對應的key private static final String TICKET = "ticket"; /** * 外部獲取簽名入口類 * * @param appUrl 應用的url * @return */ public static Map<String, Object> getSignature(String appUrl, String appId, String secret, String url, String urlpath) { // 生成簽名的隨機串 String noncestr = RandomUtil.getStringRandom(4); if (appUrl == null || "".equals(appUrl)) { return null; } String signature = null; Token accessTocken = getToken(appId, secret, System.currentTimeMillis() / 1000); Token accessTicket = getTicket(accessTocken.getToken(), System.currentTimeMillis() / 1000); signature = signature(accessTicket.getTicket(), cacheAddTime, noncestr, appUrl); System.out.println("-=-=-=-=-=-=-=-=appUrl:" + appUrl); System.out.println("-=-=-=-=-=-=-=-=token:" + accessTocken.getToken()); System.out.println("-=-=-=-=-=-=-=-=ticket:" + accessTicket.getTicket()); System.out.println("-=-=-=-=-=-=-=-=signature:" + signature); System.out.println("-=-=-=-=-=-=-=-=timestamp:" + cacheAddTime); Map<String, Object> map = new HashMap<>(); map.put("appId", appId); map.put("timestamp", cacheAddTime); map.put("nonceStr", noncestr); map.put("appUrl", appUrl); map.put("signature", signature); map.put("url", url); map.put("urlpath", urlpath); return map; } /** * 獲得Token * * @return */ public static String getToken(String appId, String secret) { Token accessTocken = getToken(appId, secret, System.currentTimeMillis() / 1000); return accessTocken.getToken(); } /** * 簽名 * * @param timestamp * @return */ private static String signature(String jsapi_ticket, String timestamp, String noncestr, String url) { jsapi_ticket = "jsapi_ticket=" + jsapi_ticket; timestamp = "timestamp=" + timestamp; noncestr = "noncestr=" + noncestr; url = "url=" + url; String[] arr = new String[]{jsapi_ticket, noncestr, timestamp, url}; // 將token、timestamp、nonce,url參數(shù)進行字典序排序 Arrays.sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); if (i != arr.length - 1) { content.append("&"); } } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 將三個參數(shù)字符串拼接成一個字符串進行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; return tmpStr; } /** * 獲取access_token * * @param appid 憑證 * @param appsecret 密鑰 * @return */ public static Token getToken(String appid, String appsecret, long currentTime) { Token tockenTicketCache = getTokenTicket(TOKEN); Token Token = null; if (tockenTicketCache != null && (currentTime - tockenTicketCache.getAddTime() <= tockenTicketCache.getExpiresIn())) {// 緩存存在并且沒過期 System.out.println("==========緩存中token已獲取時長為:" + (currentTime - tockenTicketCache.getAddTime()) + "毫秒,可以重新使用"); return tockenTicketCache; } System.out.println("==========緩存中token不存在或已過期==============="); String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); // 如果請求成功 if (null != jsonObject) { Token = new Token(); Token.setToken(jsonObject.getString("access_token")); Token.setExpiresIn(jsonObject.getIntValue("expires_in") / 2);// 正常過期時間是7200秒,此處設置3600秒讀取一次 System.out.println("==========tocket緩存過期時間為:" + Token.getExpiresIn() + "毫秒"); Token.setAddTime(currentTime); updateToken(TOKEN, Token); } return Token; } /** * 獲取ticket * * @param token * @return */ private static Token getTicket(String token, long currentTime) { Token tockenTicketCache = getTokenTicket(TICKET); Token Token = null; if (tockenTicketCache != null && (currentTime - tockenTicketCache.getAddTime() <= tockenTicketCache.getExpiresIn())) {// 緩存中有ticket System.out.println("==========緩存中ticket已獲取時長為:" + (currentTime - tockenTicketCache.getAddTime()) + "毫秒,可以重新使用"); return tockenTicketCache; } System.out.println("==========緩存中ticket不存在或已過期==============="); String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", token); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); // 如果請求成功 if (null != jsonObject) { Token = new Token(); Token.setTicket(jsonObject.getString("ticket")); Token.setExpiresIn(jsonObject.getIntValue("expires_in") / 2);// 正常過期時間是7200秒,此處設置3600秒讀取一次 System.out.println("==========ticket緩存過期時間為:" + Token.getExpiresIn() + "毫秒"); Token.setAddTime(currentTime); updateToken(TICKET, Token); } return Token; } /** * 發(fā)起https請求并獲取結果 * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數(shù)據(jù) * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值) */ private static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 創(chuàng)建SSLContext對象,并使用我們指定的信任管理器初始化 TrustManager[] tm = {new MyX509TrustManager()}; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext對象中得到SSLSocketFactory對象 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); // 設置請求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 當有數(shù)據(jù)需要提交時 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.parseObject(buffer.toString()); // jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { System.out.println("Weixin server connection timed out."); } catch (Exception e) { System.out.println("https request error:{}" + e.getMessage()); } return jsonObject; } /** * 將字節(jié)數(shù)組轉換為十六進制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 將字節(jié)轉換為十六進制字符串 * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } /** * 從緩存中讀取token或者ticket * * @return */ private static Token getTokenTicket(String key) { if (TOKEN_TICKET_CACHE != null && TOKEN_TICKET_CACHE.get(key) != null) { System.out.println("==========從緩存中獲取到了" + key + "成功==============="); return TOKEN_TICKET_CACHE.get(key); } return null; } /** * 更新緩存中token或者ticket * * @return */ private static void updateToken(String key, Token accessTocken) { if (TOKEN_TICKET_CACHE != null && TOKEN_TICKET_CACHE.get(key) != null) { TOKEN_TICKET_CACHE.remove(key); System.out.println("==========從緩存中刪除" + key + "成功==============="); } TOKEN_TICKET_CACHE.put(key, accessTocken); cacheAddTime = String.valueOf(accessTocken.getAddTime());// 更新緩存修改的時間 System.out.println("==========更新緩存中" + key + "成功==============="); } }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。