微信分享接口开发

先说句题外话:微信已经不支持自定义按钮调用微信分享了,只能自定义分享内容,然后使用官方的按钮来进行分享操作,。。。

微信分享接口开发核心使用的是微信的js-sdk,下面是官网文档上的使用步骤

1.1 JSSDK使用步骤
1.1.1 步骤一:绑定域名
1.1.2 步骤二:引入JS文件
1.1.3 步骤三:通过config接口注入权限验证配置
1.1.4 步骤四:通过ready接口处理成功验证
1.1.5 步骤五:通过error接口处理失败验证

其中绑定域名和引入js文件都没什么好说的,安装官方文档来即可。

关键的是第三步:通过config接口注入权限验证配置。官网上对于这一步骤讲述的十分简单,我在这里详细阐述一番。

wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});


对于上述参数,appId我就不用讲了,从微信公众号后台上可以拿到。timestamp和nonceStr是我们自己生成的,也很简单。唯一麻烦得是 signature签名的生成。

生成signature需要两个步骤,下面是这两个步骤

1、我们需要从微信获取 jsapi_ticket    jsapi_ticket是公众号用于调用微信JS接口的临时票据,需要通过access_token来获取。

  注: jsapi_ticket  和  access_token有效时间都为7200秒,即两个小时。。需要服务器存储且定时刷新的。。如有不懂,可参看我的这篇博客。 spring通过定时任务存储并定时刷新access_token、jsapi_ticket


2、 对于生成的 j sapi_ticket  ,我们需要和 timestamp、 nonceStr和当前页面的url通过签名算法生成 signature


现在我们来一一讲述上面的两个步骤,首先,第一步获取jsapi_ticket 

代码如下:
    //此处的token指的是access_token
    public static String getJsApiTicket(String token) throws Exception{
      if(token==null||token=="") {
            return "";
      }
        String url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi";
        String result= HttpsRequestUtil.doGet(url);
        ObjectMapper mapper=new ObjectMapper();
        JsonNode node = mapper.readTree(result);
        return node.get("ticket").textValue();
    }



什么??不知道access_token怎么获取???好吧,我顺便讲一下。
    public static String initToken() throws Exception{
        String tokenUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+SECRET;  
        String result=HttpsRequestUtil.doGet(tokenUrl);
        ObjectMapper mapper=new ObjectMapper();
        return mapper.readTree(result).get("access_token").textValue();   
    }



顺便给一下核心类 HttpsRequestUtil和依赖类 MyX509TrustManager。。这两个类的核心代码是从网上百度来的,,感谢贡献的大神!!
代码见下:

package com.wx.jlyc.wx.util;

import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @Author: Yun
 * @Description: 证书信任管理器,为了能够发送https请求
 * @Date: Created in 2017-11-29 14:51
 */
public class MyX509TrustManager implements X509TrustManager {

    // 检查客户端证书
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 检查服务器端证书
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 返回受信任的X509证书数组
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

package com.wx.jlyc.wx.util;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.URL;

/**
 * @Author: Yun
 * @Description: HTTPS请求工具
 * @Date: Created in 2017-12-26 16:03
 */
public class HttpsRequestUtil {


    /**
     * 发送get请求
     * @param href 请求的url
     * @return
     */
    public static String doGet(String href) {
        //建立连接
        URL url;
        HttpsURLConnection httpUrlConn=null;
        InputStream inputStream=null;
        BufferedReader bufferedReader=null;
        InputStreamReader inputStreamReader=null;
        try {
            url = new URL(href);
            httpUrlConn = (HttpsURLConnection) url.openConnection();

            // 创建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();
            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod("GET");
            // 取得输入流
            inputStream = httpUrlConn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            //读取响应内容
            StringBuffer buffer = new StringBuffer();
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 释放资源
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpUrlConn.disconnect();
        }
        return null;
    }

    /**
     * 发送post请求
     * @param href 请求的url
     * @param json 请求的参数(json格式)
     * @return
     */
    public static String doPost(String href,String json){
        URL url;
        HttpsURLConnection httpUrlConn=null;
        InputStream inputStream=null;
        BufferedReader bufferedReader=null;
        InputStreamReader inputStreamReader=null;
        try {
            url = new URL(href);
            httpUrlConn = (HttpsURLConnection) url.openConnection();

            // 创建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();

            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod("POST");

            //将menu数据作为请求参数
            OutputStream outputStream = httpUrlConn.getOutputStream();
            // 注意编码格式,防止中文乱码
            outputStream.write(json.getBytes("UTF-8"));
            outputStream.close();

            // 取得输入流
            inputStream = httpUrlConn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            //读取响应内容
            StringBuffer buffer = new StringBuffer();
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 释放资源
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpUrlConn.disconnect();
        }
        return null;
    }

}



这样一来,微信的jsapi_ticket我们已经获取到了。。接下来就是将各个参数通过签名算法生成 signature签名了。

代码见下:
   /**
       * 获取微信的js config接口需要的参数
       * @param url 页面的url
       * @return
       * @throws Exception
       */
      @PostMapping("/config")
      @ResponseBody
      public Msg getWxJsConfig(String url) throws Exception {
            WxToken wx_token=tokenService.getToken();
            //生成随机串
          String nonceStr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
          //生成时间戳
          String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
          //使用url键值对的方式拼接字符串
          String str = "jsapi_ticket="+wx_token.getJsapiTicket()+"&noncestr="+nonceStr+"×tamp="+timestamp+"&url="+url; 
          //对字符串进行SHA-1方式加密
          MessageDigest md = MessageDigest.getInstance("SHA-1");
          byte[] digest = md.digest(str.getBytes());
          String signature = byteToStr(digest);        
          return Msg.success().add("appId", TokenUtils.APPID).add("timestamp", timestamp).add("nonceStr", nonceStr).add("signature", signature);    
      }
      
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }
    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;
    }


安装上述做法,我们就可以获取到config接口的需要的所有参数了。。。

一般来说,我们可以通过ajax请求后台,将appId、timestamp、nonceStr、signature获取到。。然后在回调函数中进行微信分享内容的设置了,,,

js代码见下。。。

           $.ajax({
                           url:ip+'/wx/config',
                           type:'post',
                           data:{url:location.href},
                           success:function(res){
                                 console.log(res);
                                 if(res.code==200){
                                       wx.config({
                                              debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                                              appId: res.extend.appId, // 必填,公众号的唯一标识
                                              timestamp: res.extend.timestamp, // 必填,生成签名的时间戳
                                              nonceStr: res.extend.nonceStr, // 必填,生成签名的随机串
                                              signature: res.extend.signature,// 必填,签名,见附录1
                                              jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                                          });
                                  wx.ready(function(){
                                    wx.onMenuShareAppMessage({
                                        title: $("#showName").text(), // 分享标题
                                        link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                                        imgUrl:$("#video").attr("poster"), // 分享图标
                                        success: function () {
                                          alert("分享到朋友成功");
                                        },
                                        cancel: function () {
                                          alert("取消分享");
                                        }
                                    });   
                                    
                                    wx.onMenuShareTimeline({
                                          title: $("#showName").text(), // 分享标题
                                        link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                                        imgUrl:$("#video").attr("poster"), // 分享图标
                                        success: function () {
                                          alert("分享到朋友圈成功");
                                        },
                                        cancel: function () {
                                          alert("取消分享");
                                        }
                                    }); 
                                    
                                 });
                             }
                       }
                });






猜你喜欢

转载自blog.csdn.net/qq_29992111/article/details/78961206
今日推荐