国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java開發(fā)微信分享到朋友圈功能

2019-11-26 14:03:40
字體:
供稿:網(wǎng)友

微信分享功能開發(fā)

用了一天時間,把微信發(fā)送給朋友和分享到朋友圈功能開發(fā)出來,在這里給大家分享一下,避免大家走彎路。

一、服務器端程序

package com.wiimedia.controller;import java.io.IOException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.google.gson.Gson;import com.wiimedia.model.Ticket;import com.wiimedia.service.ArticleSolrService;import com.wiimedia.service.TicketRepository;import com.wiimedia.service.TicketRepositorySolr;import com.wiimedia.utils.GetRandomStr;import com.wiimedia.utils.SignatureBean;import com.wiimedia.utils.weixin.WeixinUtil;/** *  *  *<p>Project:mryl_phone_v2</p>  *  *<p>Package:com.wiimedia.controller</p>  *  *<p>Description:微信分享Controller</p> * *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-15 上午09:34:10 * */@Controller@RequestMapping("/WeixinshareController/Api/Inteface")public class WeixinshareController { @Autowired private TicketRepositorySolr ticketRepositorySolr; @RequestMapping("/getSignature") public String getSignature( HttpServletRequest request,  HttpServletResponse response) throws IOException, ParseException{ //獲取簽名頁面鏈接 String url = request.getParameter("url"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //從數(shù)據(jù)庫中獲取標簽,并檢查標簽是否過期 Ticket oldticket = ticketRepositorySolr.getTicketById("20160114wiimediamrylsong1152"); if(oldticket==null){//第一次訪問,標簽不存在。  executeTicket(response,"1",url,format);  return null; }else{//標簽存在,判斷標簽是否超時  String oldAcquiretime = oldticket.getAcquiretime();  long difference=format.parse(format.format(new Date())).getTime()-format.parse(oldAcquiretime).getTime();  if(difference>7100000){//標簽超時,重新到微信服務器請求標簽超時時間為7200秒(7200000毫秒)  executeTicket(response,"2",url,format);  return null;   }else{//標簽未超時  /**    * 注意事項         * 1.簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。   * 2.簽名用的url必須是調(diào)用JS接口頁面的完整URL。      * 3.出于安全考慮,開發(fā)者必須在服務器端實現(xiàn)簽名的邏輯。    *    ****根據(jù)第1點要求  signature 配置的時候很容易出錯,需要把生成 Ticket的 noncestr和 timestamp傳給客戶端***   */  String signature = signature(oldticket.getTicket(),oldticket.getTimestamp(),oldticket.getNoncestr(),url);  SignatureBean signatureBean = new SignatureBean();  signatureBean.setNoncestr(oldticket.getNoncestr());  signatureBean.setSignature(signature);  signatureBean.setTimestamp(oldticket.getTimestamp());  signatureBean.setUrl(url);  response.setContentType("text/html;charset=UTF-8");  response.getWriter().print(new Gson().toJson(signatureBean));  return null;   }  } } /** *  *<p>Project:mryl_phone_v2</p>  *  *<p>:mryl_phone_v2</p>  *  *<p>Description:更新和獲取ticket的方法,因為用的solr所以更新和新增是一樣的ID無則添加,有責更新</p> * *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-15 上午09:45:00  * */ public void executeTicket(HttpServletResponse response,String flag,String url,SimpleDateFormat format) throws IOException{ //獲取簽名隨即字符串 GetRandomStr randomStr = new GetRandomStr(); String noncestr = randomStr.getRandomString(15); //獲取簽名時間戳 String timestamp = Long.toString(System.currentTimeMillis()); //請求accessToken String accessTokenUrl ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=您的APPID&secret=您的密匙"; String tokenJson = WeixinUtil.httpRequest(accessTokenUrl, "GET", null); Gson gson = new Gson(); ShareAccess_Token token = gson.fromJson(tokenJson, ShareAccess_Token.class); String to= token.getAccess_token(); //獲取標簽 String urlTicket ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+to+"&type=jsapi"; String ticketJson = WeixinUtil.httpRequest(urlTicket, "GET", null); Ticket ticket = gson.fromJson(ticketJson, Ticket.class); String t = ticket.getTicket(); //String uuid = UUID.randomUUID().toString().trim().replaceAll("-", ""); //我的Ticket ID是寫死的 String acquiretime = format.format(new Date()); ticket.setTid("20160114wiimediamrylsong1152"); ticket.setAcquiretime(acquiretime); ticket.setTimestamp(timestamp); ticket.setNoncestr(noncestr); //因為用的SOLR所以更新和添加的方法是一樣的,可以根據(jù)自己具體需求進行修改,本文不再貼出代碼. if(flag.equals("2")){  ticketRepositorySolr.addTicketToSolr(ticket);  }else{  ticketRepositorySolr.addTicketToSolr(ticket); } /**   * 注意事項        * 1.簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。  * 2.簽名用的url必須是調(diào)用JS接口頁面的完整URL。     * 3.出于安全考慮,開發(fā)者必須在服務器端實現(xiàn)簽名的邏輯。   *   *根據(jù)第1點要求  signature 配置的時候很容易出錯,需要把生成 Ticket的 noncestr和 timestamp傳給客戶端*  */ String signature = signature(t,timestamp,noncestr,url); SignatureBean signatureBean = new SignatureBean(); signatureBean.setNoncestr(noncestr); signatureBean.setSignature(signature); signatureBean.setTimestamp(timestamp); signatureBean.setUrl(url); response.setContentType("text/html;charset=UTF-8"); response.getWriter().print(new Gson().toJson(signatureBean)); } /** *  *<p>Project:mryl_phone_v2</p>  *  *<p>:mryl_phone_v2</p>  *  *<p>Description:根據(jù)標簽,時間戳,密匙,URL進行簽名</p> * *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-15 上午09:37:13  * */ private 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, timestamp, noncestr, 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; } /** * 將字節(jié)轉(zhuǎn)換為十六進制字符串 *  * @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; } /** * 將字節(jié)數(shù)組轉(zhuǎn)換為十六進制字符串 *  * @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; } class ShareAccess_Token{ private String access_token; private String expires_in; public String getAccess_token() {  return access_token; } public void setAccess_token(String accessToken) {  access_token = accessToken; } public String getExpires_in() {  return expires_in; } public void setExpires_in(String expiresIn) {  expires_in = expiresIn; } }}

二、客戶端代碼.

<script type="text/javascript">  var url = window.location.href;  var articleId = "";  var shareTitle="明日醫(yī)療資訊";  var shareImgUrl="";  var userinfo = localStorage.getItem("_userinfo");  var timestamp;  var noncestr;  var signature;  //獲取簽名  $.ajax({   type: "GET",   url: "WeixinshareController/Api/Inteface/getSignature",   //data:{timestamp:timestamp,noncestr:noncestr,url:url},   data:{url:url},   success: function(data){    var objData=JSON.parse(data);     timestamp=objData.timestamp;     noncestr=objData.noncestr;     signature=objData.signature;     console.log(objData);     wxShare();   }   });  function wxShare(){  wx.config({  debug: false, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。  appId: '您的appid', // 和獲取Ticke的必須一樣------必填,公眾號的唯一標識  timestamp:timestamp, // 必填,生成簽名的時間戳  nonceStr: noncestr, // 必填,生成簽名的隨機串  signature: signature,// 必填,簽名,見附錄1  jsApiList: [  'onMenuShareAppMessage'  ] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2  });  }  wx.ready(function(){   //config信息驗證后會執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,   //config是一個客戶端的異步操作,所以如果需要在頁面加載時就調(diào)用相關(guān)接口,則須把相關(guān)   //接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對于用戶觸發(fā)時才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。  //----------“分享給朋友”  wx.onMenuShareAppMessage({   title: "明日醫(yī)療資訊", // 分享標題   desc: shareTitle, // 分享描述   link: url, // 分享鏈接   imgUrl: shareImgUrl, // 分享圖標   type: '', // 分享類型,music、video或link,不填默認為link   dataUrl: '', // 如果type是music或video,則要提供數(shù)據(jù)鏈接,默認為空   success: function () {    // 用戶確認分享后執(zhí)行的回調(diào)函數(shù)、   },   cancel: function () {    // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)   }  });  //------------"分享到朋友圈"  wx.onMenuShareTimeline({   title: '明日醫(yī)療資訊', // 分享標題   link: '', // 分享鏈接   imgUrl: shareImgUrl, // 分享圖標   success: function () {    // 用戶確認分享后執(zhí)行的回調(diào)函數(shù)   },   cancel: function () {    // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)   }  });  //-------------分享到QQ  wx.onMenuShareQQ({   title: '明日醫(yī)療資訊', // 分享標題   desc: shareTitle, // 分享描述   link: '', // 分享鏈接   imgUrl: shareImgUrl, // 分享圖標   success: function () {    // 用戶確認分享后執(zhí)行的回調(diào)函數(shù)   },   cancel: function () {    // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)   }  });  //-------------分享到QQ空間  wx.onMenuShareQZone({   title: '明日醫(yī)療資訊', // 分享標題   desc: shareTitle, // 分享描述   link: '', // 分享鏈接   imgUrl: shareImgUrl, // 分享圖標   success: function () {    // 用戶確認分享后執(zhí)行的回調(diào)函數(shù)   },   cancel: function () {    // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)   }  });  });

三、服務器需要的工具類和Model

① Ticket

package com.wiimedia.model;public class Ticket{ private String tid; private String ticket;  private String errcode; private String errmsg;  private String expires_in; private String acquiretime; private String noncestr; private String timestamp; public Ticket(String tid, String ticket, String errcode, String errmsg,  String expiresIn, String acquiretime, String noncestr,  String timestamp) { super(); this.tid = tid; this.ticket = ticket; this.errcode = errcode; this.errmsg = errmsg; expires_in = expiresIn; this.acquiretime = acquiretime; this.noncestr = noncestr; this.timestamp = timestamp; } public String getTid() { return tid; } public void setTid(String tid) { this.tid = tid; } public String getTicket() { return ticket; } public void setTicket(String ticket) { this.ticket = ticket; } public String getErrcode() { return errcode; } public void setErrcode(String errcode) { this.errcode = errcode; } public String getErrmsg() { return errmsg; } public void setErrmsg(String errmsg) { this.errmsg = errmsg; } public String getExpires_in() { return expires_in; } public void setExpires_in(String expiresIn) { expires_in = expiresIn; } public String getAcquiretime() { return acquiretime; } public void setAcquiretime(String acquiretime) { this.acquiretime = acquiretime; } public String getNoncestr() { return noncestr; } public void setNoncestr(String noncestr) { this.noncestr = noncestr; } public String getTimestamp() { return timestamp; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; }}

② 添加到數(shù)據(jù)庫的業(yè)務根據(jù)自己需要進行實現(xiàn).
③ GetRandomStr

package com.wiimedia.utils;import java.util.Random;public class GetRandomStr { /** *  *<p>Project:mryl_phone_v2</p>  *  *<p>:mryl_phone_v2</p>  *  *<p>Description:生成隨即字符串 </p> * *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-14 上午11:14:46  * */ public String getRandomString(int length) { String base = "abcdefghijklmnopqrstuvwxyz0123456789";  Random random = new Random();  StringBuffer sb = new StringBuffer();  for (int i = 0; i < length; i++) {   int number = random.nextInt(base.length());   sb.append(base.charAt(number));  }  return sb.toString();  }}

 ④ SignatureBean

package com.wiimedia.utils;public class SignatureBean { private String noncestr; private String url; private String timestamp; private String signature; public String getNoncestr() { return noncestr; } public void setNoncestr(String noncestr) { this.noncestr = noncestr; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getTimestamp() { return timestamp; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; } public String getSignature() { return signature; } public void setSignature(String signature) { this.signature = signature; }}

⑤ WeixinUtil

package com.wiimedia.utils.weixin;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 javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;/** *  *<p>Project:mryl_phone_v2</p>  *  *<p>:mryl_phone_v2</p>  *  *<p>Description:公眾平臺接口工具類</p> * *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-15 上午09:37:13  * */public class WeixinUtil { /**  * 發(fā)起https請求并獲取結(jié)果  *  * @param requestUrl 請求地址  * @param requestMethod 請求方式(GET、POST)  * @param outputStr 提交的數(shù)據(jù)  * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值)  */  public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {  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);   // 設(shè)置請求方式(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();   }   // 將返回的輸入流轉(zhuǎn)換成字符串   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();   return buffer.toString();  } catch (ConnectException ce) {   ce.printStackTrace();  } catch (Exception e) {   e.printStackTrace(); }  return "";  }}

 四、至此,分享功能已經(jīng)開發(fā)完成,但是,在生成signature的時候會遇到很多問題,這里提供一些wx.config失敗的排錯方法。

① 確認自己的生成的signature是否正確
在微信提供的http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign進行校驗

② wx.config中使用的noncestr, timestamp與用以簽名中的對應noncestr, timestamp是否一致一致…如上面(一.服務器代碼)
(有可能因為JS頁面加載順序問題,服務器生成的signature,noncestr,timestamp在wx.config中沒有獲取到)。

③ 確認url是頁面完整的url,包括GET參數(shù)部分
需要去掉#后面的部分

④ config 中的 appid 與用來獲取 jsapi_ticket 的 appid 是否一致

⑤ 報錯{errmsg:config:ok}是debug的正常返回把調(diào)試模式關(guān)掉就OK
wx.config debug: false,

本文已被整理到了《Android微信開發(fā)教程匯總》,《java微信開發(fā)教程匯總》歡迎大家學習閱讀。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 页游| 新晃| 沅江市| 铁岭县| 沙雅县| 永寿县| 东台市| 北川| 泸州市| 中江县| 汝州市| 霍山县| 拉孜县| 太湖县| 富民县| 申扎县| 方山县| 盐城市| 武平县| 杭州市| 额尔古纳市| 长阳| 镇安县| 盐亭县| 绩溪县| 彰化市| 宣汉县| 通化市| 灵台县| 罗江县| 密云县| 嘉鱼县| 基隆市| 简阳市| 淳化县| 新民市| 藁城市| 英山县| 五寨县| 道真| 海门市|