亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Home WeChat Applet WeChat Development Java development of WeChat sharing to Moments function

Java development of WeChat sharing to Moments function

Jan 16, 2017 pm 01:52 PM

WeChat sharing function development

It took a day to develop the function of sending WeChat to friends and sharing to Moments. I would like to share it with you here to avoid detours.

1. Server-side program

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ù)庫中獲取標(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接口頁面的完整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接口頁面的完整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 = { &#39;0&#39;, &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;, &#39;9&#39;, &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39; };
  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;
  }
 
 }
}

2. Client code.

<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: &#39;您的appid&#39;, // 和獲取Ticke的必須一樣------必填,公眾號(hào)的唯一標(biāo)識(shí)
    timestamp:timestamp, // 必填,生成簽名的時(shí)間戳
    nonceStr: noncestr, // 必填,生成簽名的隨機(jī)串
    signature: signature,// 必填,簽名,見附錄1
    jsApiList: [
    &#39;onMenuShareAppMessage&#39;
    ] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
   });
   }
   wx.ready(function(){
     //config信息驗(yàn)證后會(huì)執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,
     //config是一個(gè)客戶端的異步操作,所以如果需要在頁面加載時(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: &#39;&#39;, // 分享類型,music、video或link,不填默認(rèn)為link
     dataUrl: &#39;&#39;, // 如果type是music或video,則要提供數(shù)據(jù)鏈接,默認(rèn)為空
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)、
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
    //------------"分享到朋友圈"
    wx.onMenuShareTimeline({
     title: &#39;明日醫(yī)療資訊&#39;, // 分享標(biāo)題
     link: &#39;&#39;, // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
    //-------------分享到QQ
    wx.onMenuShareQQ({
     title: &#39;明日醫(yī)療資訊&#39;, // 分享標(biāo)題
     desc: shareTitle, // 分享描述
     link: &#39;&#39;, // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
    //-------------分享到QQ空間
    wx.onMenuShareQZone({
     title: &#39;明日醫(yī)療資訊&#39;, // 分享標(biāo)題
     desc: shareTitle, // 分享描述
     link: &#39;&#39;, // 分享鏈接
     imgUrl: shareImgUrl, // 分享圖標(biāo)
     success: function () { 
      // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
     },
     cancel: function () { 
      // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
     }
    });
 
   });

3. Tool classes and Model required by the server

① 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;
 }
 
 
}

② The business added to the database is implemented according to your own needs.
③ 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 ""; 
 }
}

4. So far , the sharing function has been developed, but many problems will be encountered when generating signatures. Here are some troubleshooting methods for wx.config failure.

① Confirm whether your generated signature is correct
Verify at http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign provided by WeChat

② Are the noncestr and timestamp used in wx.config consistent with the corresponding noncestr and timestamp used in the signature... As shown above (1. Server code)
(It may be due to the JS page loading order problem, the server The generated signature, noncestr, and timestamp are not obtained in wx.config).

③ Confirm that the url is the complete url of the page, including the GET parameter part
Need to remove the part after

#④ Is the appid in config consistent with the appid used to obtain jsapi_ticket

⑤ The error {errmsg: config:ok} is the normal return of debug. Just turn off the debug mode and OK
wx.config debug: false,

The above is the entire content of this article , I hope it will be helpful to everyone's learning, and I also hope that everyone will support the PHP Chinese website.

For more articles related to Java development WeChat sharing to Moments function, please pay attention to the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1488
72