溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2021-01-18 11:24:17 來源:億速云 閱讀:360 作者:小新 欄目:移動(dòng)開發(fā)

小編給大家分享一下java如何開發(fā)微信分享到朋友圈功能,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

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

一、服務(wù)器端程序

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{
  //獲取簽名頁(yè)面鏈接
  String url = request.getParameter("url");
  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  //從數(shù)據(jù)庫(kù)中獲取標(biāo)簽,并檢查標(biāo)簽是否過期
  Ticket oldticket = ticketRepositorySolr.getTicketById("20160114wiimediamrylsong1152");
  if(oldticket==null){//第一次訪問,標(biāo)簽不存在。
   executeTicket(response,"1",url,format);
   return null;
  }else{//標(biāo)簽存在,判斷標(biāo)簽是否超時(shí)
   String oldAcquiretime = oldticket.getAcquiretime();
   long difference=format.parse(format.format(new Date())).getTime()-format.parse(oldAcquiretime).getTime();
   if(difference>7100000){//標(biāo)簽超時(shí),重新到微信服務(wù)器請(qǐng)求標(biāo)簽超時(shí)時(shí)間為7200秒(7200000毫秒)
    executeTicket(response,"2",url,format);
    return null; 
   }else{//標(biāo)簽未超時(shí)
    /** 
     * 注意事項(xiàng)           
     * 1.簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
     * 2.簽名用的url必須是調(diào)用JS接口頁(yè)面的完整URL。      
     * 3.出于安全考慮,開發(fā)者必須在服務(wù)器端實(shí)現(xiàn)簽名的邏輯。 
     * 
     ****根據(jù)第1點(diǎn)要求   signature 配置的時(shí)候很容易出錯(cuò),需要把生成 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的方法,因?yàn)橛玫膕olr所以更新和新增是一樣的ID無則添加,有責(zé)更新</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);
  //獲取簽名時(shí)間戳
  String timestamp = Long.toString(System.currentTimeMillis());
  //請(qǐng)求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();
  //獲取標(biāo)簽
  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);
  //因?yàn)橛玫腟OLR所以更新和添加的方法是一樣的,可以根據(jù)自己具體需求進(jìn)行修改,本文不再貼出代碼.
  if(flag.equals("2")){
   ticketRepositorySolr.addTicketToSolr(ticket); 
  }else{
   ticketRepositorySolr.addTicketToSolr(ticket);
  }
  /** 
   * 注意事項(xiàng)           
   * 1.簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
   * 2.簽名用的url必須是調(diào)用JS接口頁(yè)面的完整URL。      
   * 3.出于安全考慮,開發(fā)者必須在服務(wù)器端實(shí)現(xiàn)簽名的邏輯。 
   * 
   *根據(jù)第1點(diǎn)要求   signature 配置的時(shí)候很容易出錯(cuò),需要把生成 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ù)標(biāo)簽,時(shí)間戳,密匙,URL進(jìn)行簽名</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ù)進(jìn)行字典序排序
  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");
   // 將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密
   byte[] digest = md.digest(content.toString().getBytes());
   tmpStr = byteToStr(digest);
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }
 
  content = null;
  return tmpStr;
 }
 /**
  * 將字節(jié)轉(zhuǎn)換為十六進(jì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)換為十六進(jì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的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。
    appId: '您的appid', // 和獲取Ticke的必須一樣------必填,公眾號(hào)的唯一標(biāo)識(shí)
    timestamp:timestamp, // 必填,生成簽名的時(shí)間戳
    nonceStr: noncestr, // 必填,生成簽名的隨機(jī)串
    signature: signature,// 必填,簽名,見附錄1
    jsApiList: [
    'onMenuShareAppMessage'
    ] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
   });
   }
   wx.ready(function(){
     //config信息驗(yàn)證后會(huì)執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,
     //config是一個(gè)客戶端的異步操作,所以如果需要在頁(yè)面加載時(shí)就調(diào)用相關(guān)接口,則須把相關(guān)
     //接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對(duì)于用戶觸發(fā)時(shí)才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。
 
    //----------“分享給朋友”
    wx.onMenuShareAppMessage({
     title: "明日醫(yī)療資訊", // 分享標(biāo)題
     desc: shareTitle, // 分享描述
     link: url, // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     type: '', // 分享類型,music、video或link,不填默認(rèn)為link
     dataUrl: '', // 如果type是music或video,則要提供數(shù)據(jù)鏈接,默認(rèn)為空
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)、
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
    //------------"分享到朋友圈"
    wx.onMenuShareTimeline({
     title: '明日醫(yī)療資訊', // 分享標(biāo)題
     link: '', // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
    //-------------分享到QQ
    wx.onMenuShareQQ({
     title: '明日醫(yī)療資訊', // 分享標(biāo)題
     desc: shareTitle, // 分享描述
     link: '', // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
    //-------------分享到QQ空間
    wx.onMenuShareQZone({
     title: '明日醫(yī)療資訊', // 分享標(biāo)題
     desc: shareTitle, // 分享描述
     link: '', // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
 
   });

三、服務(wù)器需要的工具類和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ù)庫(kù)的業(yè)務(wù)根據(jù)自己需要進(jìn)行實(shí)現(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:公眾平臺(tái)接口工具類</p>
  *
  *<p>Company:Wiimedia</p>
  *
  *@Athor:SongJia
  *
  *@Date:2016-7-15 上午09:37:13 
  *
  */
public class WeixinUtil {
 
 /** 
  * 發(fā)起https請(qǐng)求并獲取結(jié)果 
  * 
  * @param requestUrl 請(qǐng)求地址 
  * @param requestMethod 請(qǐng)求方式(GET、POST) 
  * @param outputStr 提交的數(shù)據(jù) 
  * @return JSONObject(通過JSONObject.get(key)的方式獲取json對(duì)象的屬性值) 
  */
 public static String httpRequest(String requestUrl, String requestMethod, String outputStr) { 
 
  StringBuffer buffer = new StringBuffer(); 
  try { 
   // 創(chuàng)建SSLContext對(duì)象,并使用我們指定的信任管理器初始化 
   TrustManager[] tm = { new MyX509TrustManager() }; 
   SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 
   sslContext.init(null, tm, new java.security.SecureRandom()); 
   // 從上述SSLContext對(duì)象中得到SSLSocketFactory對(duì)象 
   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è)置請(qǐng)求方式(GET/POST) 
   httpUrlConn.setRequestMethod(requestMethod); 
 
   if ("GET".equalsIgnoreCase(requestMethod)) 
    httpUrlConn.connect(); 
 
   // 當(dāng)有數(shù)據(jù)需要提交時(shí) 
   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的時(shí)候會(huì)遇到很多問題,這里提供一些wx.config失敗的排錯(cuò)方法。

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

② wx.config中使用的noncestr, timestamp與用以簽名中的對(duì)應(yīng)noncestr, timestamp是否一致一致…如上面(一.服務(wù)器代碼)
(有可能因?yàn)镴S頁(yè)面加載順序問題,服務(wù)器生成的signature,noncestr,timestamp在wx.config中沒有獲取到)。

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

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

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

看完了這篇文章,相信你對(duì)“java如何開發(fā)微信分享到朋友圈功能”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI