java如何开发微信分享到朋友圈功能

小编给大家分享一下java如何开发微信分享到朋友圈功能,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

创新互联建站-专业网站定制、快速模板网站建设、高性价比阜城网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式阜城网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖阜城地区。费用合理售后完善,十多年实体公司更值得信赖。

微信分享功能开发

一、服务器端程序

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;
/**
 * 
 * 
 *

Project:mryl_phone_v2

   *   *

Package:com.wiimedia.controller

   *   *

Description:微信分享Controller

 *  *

Company:Wiimedia

 *  *@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");   //从数据库中获取标签,并检查标签是否过期   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必须是调用JS接口页面的完整URL。            * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。       *       ****根据第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;     }    }      }  /**   *    *

Project:mryl_phone_v2

    *    *

:mryl_phone_v2

    *    *

Description:更新和获取ticket的方法,因为用的solr所以更新和新增是一样的ID无则添加,有责更新

  *   *

Company:Wiimedia

  *   *@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所以更新和添加的方法是一样的,可以根据自己具体需求进行修改,本文不再贴出代码.   if(flag.equals("2")){    ticketRepositorySolr.addTicketToSolr(ticket);    }else{    ticketRepositorySolr.addTicketToSolr(ticket);   }   /**     * 注意事项               * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。    * 2.签名用的url必须是调用JS接口页面的完整URL。          * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。     *     *根据第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));  }    /**   *    *

Project:mryl_phone_v2

    *    *

:mryl_phone_v2

    *    *

Description:根据标签,时间戳,密匙,URL进行签名

  *   *

Company:Wiimedia

  *   *@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参数进行字典序排序   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");    // 将三个参数字符串拼接成一个字符串进行sha1加密    byte[] digest = md.digest(content.toString().getBytes());    tmpStr = byteToStr(digest);   } catch (NoSuchAlgorithmException e) {    e.printStackTrace();   }     content = null;   return tmpStr;  }  /**   * 将字节转换为十六进制字符串   *    * @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;  }  /**   * 将字节数组转换为十六进制字符串   *    * @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;   }    } }

二、客户端代码.


   var url = window.location.href;
   var articleId = "";
   var shareTitle="明日医疗资讯";
   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, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '您的appid', // 和获取Ticke的必须一样------必填,公众号的唯一标识
    timestamp:timestamp, // 必填,生成签名的时间戳
    nonceStr: noncestr, // 必填,生成签名的随机串
    signature: signature,// 必填,签名,见附录1
    jsApiList: [
    'onMenuShareAppMessage'
    ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
   });
   }
   wx.ready(function(){
     //config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
     //config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关
     //接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
 
    //----------“分享给朋友”
    wx.onMenuShareAppMessage({
     title: "明日医疗资讯", // 分享标题
     desc: shareTitle, // 分享描述
     link: url, // 分享链接
     imgUrl: shareImgUrl, // 分享图标
     type: '', // 分享类型,music、video或link,不填默认为link
     dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
     success: function () { 
      // 用户确认分享后执行的回调函数、
     },
     cancel: function () { 
      // 用户取消分享后执行的回调函数
     }
    });
    //------------"分享到朋友圈"
    wx.onMenuShareTimeline({
     title: '明日医疗资讯', // 分享标题
     link: '', // 分享链接
     imgUrl: shareImgUrl, // 分享图标
     success: function () { 
      // 用户确认分享后执行的回调函数
     },
     cancel: function () { 
      // 用户取消分享后执行的回调函数
     }
    });
    //-------------分享到QQ
    wx.onMenuShareQQ({
     title: '明日医疗资讯', // 分享标题
     desc: shareTitle, // 分享描述
     link: '', // 分享链接
     imgUrl: shareImgUrl, // 分享图标
     success: function () { 
      // 用户确认分享后执行的回调函数
     },
     cancel: function () { 
      // 用户取消分享后执行的回调函数
     }
    });
    //-------------分享到QQ空间
    wx.onMenuShareQZone({
     title: '明日医疗资讯', // 分享标题
     desc: shareTitle, // 分享描述
     link: '', // 分享链接
     imgUrl: shareImgUrl, // 分享图标
     success: function () { 
      // 用户确认分享后执行的回调函数
     },
     cancel: function () { 
      // 用户取消分享后执行的回调函数
     }
    });
 
   });

三、服务器需要的工具类和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;
 }
 
 
}

② 添加到数据库的业务根据自己需要进行实现.
③ GetRandomStr

package com.wiimedia.utils;
 
import java.util.Random;
 
public class GetRandomStr {
 /**
  * 
  *

Project:mryl_phone_v2

    *    *

:mryl_phone_v2

    *    *

Description:生成随即字符串 

  *   *

Company:Wiimedia

  *   *@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;
 
/**
  * 
  *

Project:mryl_phone_v2

    *    *

:mryl_phone_v2

    *    *

Description:公众平台接口工具类

  *   *

Company:Wiimedia

  *   *@Athor:SongJia   *   *@Date:2016-7-15 上午09:37:13    *   */ public class WeixinUtil {    /**    * 发起https请求并获取结果    *    * @param requestUrl 请求地址    * @param requestMethod 请求方式(GET、POST)    * @param outputStr 提交的数据    * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)    */  public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {      StringBuffer buffer = new StringBuffer();    try {     // 创建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();       // 当有数据需要提交时     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();     return buffer.toString();    } catch (ConnectException ce) {     ce.printStackTrace();    } catch (Exception e) {     e.printStackTrace();   }    return "";   } }

四、至此,分享功能已经开发完成,但是,在生成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参数部分
需要去掉#后面的部分

④ config 中的 appid 与用来获取 jsapi_ticket 的 appid 是否一致

⑤ 报错{errmsg:config:ok}是debug的正常返回把调试模式关掉就OK
wx.config debug: false,

看完了这篇文章,相信你对“java如何开发微信分享到朋友圈功能”有了一定的了解,如果想了解更多相关知识,欢迎关注创新互联行业资讯频道,感谢各位的阅读!


网站栏目:java如何开发微信分享到朋友圈功能
网站网址:http://ybzwz.com/article/jddeds.html