微信开发怎么加入分享人id_微信开发 获取用户微信id - CSDN
  • 现在每天都可以看到很多微信分享的链接上面有网站或者商家的自定义的分享标题,和分享链接的描述及分享出去的图像,例如下面的分享出去的链接: 上面这个是微信的js-SDK页面分享微信好友在聊天列表中显示的视觉...

    现在每天都可以看到很多微信分享的链接上面有网站或者商家的自定义的分享标题,和分享链接的描述及分享出去的图像,例如下面的分享出去的链接:

                     

         上面这个是微信的js-SDK页面分享给微信好友在聊天列表中显示的视觉效果。

          微信JS-SDK Demo :这个是微信网页分享出去的标题。

         微信JS-SDK,帮助第三方为用户提供更优质的移动web服务:这个是被分享的这个页面的分享描述。

         微信图标:这个就是自己网站或者自己自定义的图像。

         上面这个是微信官方网页分享出去的定义描述,那么怎样实现自己网站网页的自定义分享的标题,描述及分享出去的显示图片呢,下面就具体的来探讨一下微信网页第三方分享自定的实现方式。

         关于微信网页分享自定义主要有两方面的工作需要我们来做,一是:分享页面的js分享代码的编写,二是:微信分享网页的链接地址签名。

         首先来看一下网页的连接地址签名,这个功能主要是在服务端来时实现。

         第一步:基础数据的准备,需要如下数据信息:

         APPID:微信公众号的id; APP_SECRECT:公众号号的密钥。签名的网站域名(这个建议配置在配置文件中)。

         第二步:微信签名数据的准备:

        appid,secret,url将这三个参数放入map中, 键值为:appid=微信公众号的id,secret=APP_SECRECT,url=网站的域名+网页的请求地址+请求的参数。

        代码的实现方式如下:

          1. controller层的代码实现: 

    1. @RequestMapping("cover")
    2. public String identifyCover(HttpServletRequest request, HttpServletResponse response)
    3. //微信分享授权开始
    4. String appId = ;//取项目中配置的公众号id
    5. String secret = ;//取项目中配置的公众号密钥
    6. //例如我们有一个分享的链接为:http://test.weixinfwenx.cn/project/fenxiang.do?id=1&name=2;
    7. //那么domainAddr = http://test.weixinfwenx.cn,这个可以动态的配置在项目里,方便测试环境和生产
    8. //域名的切换
    9. String domainAddr = "";//项目中配置的网站的域名
    10. //这个取的是链接上的参数,例如在上面的这个链接中,id=1&name=2就是我们要动态去的参数,可能有人
    11. //会想到,这个两个参数直接写在地址中不是挺简单的为啥还要动态去获取这个参数呢;在这里我们引出了一
    12. //个微信二次分享的问题,就是别人转发的链接给你,然后你再转发给别人,在你转发给别人后这个链接的签
    13. //名就会失败,为啥呢,因为经过再次转发的链接,微信会自动加上一些自己的参数,这样会导致页面上微信
    14. //分享的链接和签名的链接不一致。直接导致自定义的标题和链接描述,显示失败,失败原因是微信默认的在
    15. //我们的分享链接上加上了&from=singlemessage。
    16. String str = request.getQueryString();
    17. Map<String, String> map = new HashMap<String, String>();
    18. map.put("appid", appId);
    19. map.put("secret", secret);
    20. String url = domainAddr + "/project/fenxiang.do?"+str; map.put("url", url);
    21. //这个地址是传给页面使用
    22. request.setAttribute("fenxurl", url);
    23. //开始微信分享链接签名
    24. Map<String, String> params = weixinService.weixinjsIntefaceSign(map);
    25. request.setAttribute("params", params);
    26. return "自己的页面";
     2.service层的实现代码:

       接口:  

    1. public interface weixinService{
    2. /**
    3. * @Title: weixinjsIntefaceSign
    4. * @Description: 微信js接口授权
    5. * @param map
    6. * @return
    7. * @return: Map<String,String>
    8. */
    9. public Map<String,String> weixinjsIntefaceSign(Map<String,String> map);
    接口实现类:

    1. public class weixinServiceImpl implements weixinService{
    2. public Map<String, String> weixinjsIntefaceSign(Map<String, String> map){
    3. //查看缓存数据是否存在
    4. String cacheAccess_token = jedis.get("access_token");
    5. String cacheTicket = jedis.get("ticket");
    6. //取出来为空的话则说明cacheAccess_token缓存过期,重新获取
    7. if(null == cacheAccess_token){
    8. ///////////////////////////////start
    9. //获取cacheAccess_token
    10. //这段代码实际开发过程中要写成一个方法,我这里为了演示方便写在了一起。
    11. StringBuffer buffer = new StringBuffer();
    12. buffer.append("https://api.weixin.qq.com/cgi-bin/token?");
    13. buffer.append("appid="+map.get("appid"));
    14. buffer.append("&secret="+map.get("secret"));
    15. buffer.append("&grant_type=client_credential");
    16. String resultMsg = SendUtils.sendGet(buffer.toString(), "UTF-8");
    17. ///////////////////// end
    18. JSONObject json = new JSONObject(resultMsg);
    19. cacheAccess_token = json.getString("access_token");
    20. jedis.set("access_token",cacheAccess_token, "NX", "EX", 3600);//单位是秒
    21. }
    22. //取出来为空的话则说明cacheTicket缓存过期,重新获取
    23. if(null == cacheTicket){
    24. ////////////////////////// start
    25. ////获得jsapi_ticket
    26. StringBuffer buffer = new StringBuffer();
    27. buffer.append("https://api.weixin.qq.com/cgi-bin/ticket/getticket?");
    28. buffer.append("access_token="+access_token);
    29. buffer.append("&type=jsapi");
    30. String ticket = SendUtils.sendGet(buffer.toString(), "UTF-8");
    31. ///////////////////// end
    32. JSONObject json2 = new JSONObject(ticket);
    33. cacheTicket = json2.getString("ticket");
    34. jedis.set("ticket",cacheTicket, "NX", "EX", 3600);//单位是秒
    35. }
    36. //生成签名
    37. SortedMap<Object,Object> params = new TreeMap<Object,Object>();
    38. params.put("timestamp", Long.toString(new Date().getTime()/1000));
    39. params.put("noncestr", this.CreateNoncestr());
    40. params.put("jsapi_ticket",cacheTicket);
    41. params.put("url",map.get("url"));//url地址
    42. StringBuffer sb = new StringBuffer();
    43. Set es = params.entrySet();
    44. Iterator it = es.iterator();
    45. while(it.hasNext()) {
    46. Map.Entry entry = (Map.Entry)it.next();
    47. String k = (String)entry.getKey();
    48. Object v = entry.getValue();
    49. sb.append(k + "=" + v + "&");
    50. }
    51. String signStr = sb.toString().substring(0, sb.toString().length()-1);
    52. String sign = Sha1.getSha1Sign(signStr);//签名
    53. Map<String, String> result = new HashMap<String,String>();
    54. result.put("timestamp",(String)params.get("timestamp"));
    55. result.put("noncestr", (String)params.get("noncestr"));
    56. result.put("signature", sign);
    57. result.put("appId",map.get("appid"));
    58. return result;
    59. return null;
    60. }
    61. private String CreateNoncestr() {
    62. String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    63. String res = "";
    64. for (int i = 0; i < 16; i++) {
    65. Random rd = new Random();
    66. res += chars.charAt(rd.nextInt(chars.length() - 1));
    67. }
    68. return res;
    69. }
    70. }

    辅助工具类:

    1. /**
    2. *
    3. * 加密工具类
    4. *
    5. */
    6. public class Sha1 {
    7. public static String getSha1Sign(String decript) {
    8. try {
    9. MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
    10. try {
    11. digest.update(decript.getBytes("UTF-8"));
    12. } catch (UnsupportedEncodingException e) {
    13. // TODO Auto-generated catch block
    14. e.printStackTrace();
    15. }
    16. byte messageDigest[] = digest.digest();
    17. // Create Hex String
    18. StringBuffer hexString = new StringBuffer();
    19. // 字节数组转换为 十六进制 数
    20. for (int i = 0; i < messageDigest.length; i++) {
    21. String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
    22. if (shaHex.length() < 2) {
    23. hexString.append(0);
    24. }
    25. hexString.append(shaHex);
    26. }
    27. return hexString.toString();
    28. } catch (NoSuchAlgorithmException e) {
    29. e.printStackTrace();
    30. }
    31. return "";
    32. }
    33. }
    http请求工具类:

    1. /**
    2. * http请求工具类
    3. *
    4. */
    5. public class SendUtils {
    6. public static String sendGet(String url,String charset){
    7. //新建客户端
    8. HttpClient httpclient = new HttpClient();
    9. GetMethod getMethod = new GetMethod(url);
    10. httpclient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
    11. httpclient.executeMethod(getMethod);
    12. String responseMsg = getMethod.getResponseBodyAsString();
    13. return responseMsg;
    14. }
    15. }
     以上是服务器端的微信签名的实现代码,下面介绍一下分享页面中js的编写。

      第一步引入微信的js文件:

       <script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

     第二步:  

    1. wx.config({
    2. debug: false,
    3. appId: '${params.appId}',
    4. timestamp: '${params.timestamp}',
    5. nonceStr: '${params.noncestr}',
    6. signature:'${params.signature}',
    7. jsApiList: [
    8. 'onMenuShareTimeline',
    9. 'onMenuShareAppMessage',
    10. 'onMenuShareQQ',
    11. 'onMenuShareWeibo',
    12. 'onMenuShareQZone'
    13. ]
    14. });
    15. wx.ready(function(){
    16. wx.checkJsApi({
    17. jsApiList: [
    18. 'onMenuShareTimeline',
    19. 'onMenuShareAppMessage',
    20. 'onMenuShareQQ',
    21. 'onMenuShareWeibo',
    22. 'onMenuShareQZone'
    23. ]
    24. });
    25. wx.checkJsApi({
    26. jsApiList: [
    27. 'onMenuShareTimeline',
    28. 'onMenuShareAppMessage',
    29. 'onMenuShareQQ',
    30. 'onMenuShareWeibo',
    31. 'onMenuShareQZone'
    32. ]
    33. });
    34. /*分享到朋友圈*/
    35. wx.onMenuShareTimeline({
    36. title: '计划书', // 分享标题
    37. desc: '保险让生活更美好!', // 分享描述
    38. link: '${fenxurl}', // 分享链接
    39. imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
    40. success: function () {
    41. // 用户确认分享后执行的回调函数
    42. },
    43. cancel: function () {
    44. // 用户取消分享后执行的回调函数
    45. }
    46. });
    47. /*分享给朋友*/
    48. wx.onMenuShareAppMessage({
    49. title: '计划书', // 分享标题
    50. desc: '保险让生活更美好!', // 分享描述
    51. link: '${fenxurl}', // 分享链接
    52. imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
    53. type: 'link', // 分享类型,music、video或link,不填默认为link
    54. dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
    55. success: function () {
    56. // 用户确认分享后执行的回调函数
    57. alert("您已分享");
    58. },
    59. cancel: function () {
    60. // 用户取消分享后执行的回调函数
    61. alert('您已取消分享');
    62. }
    63. });
    64. wx.onMenuShareQQ({
    65. title: '计划书', // 分享标题
    66. desc: '保险让生活更美好!', // 分享描述
    67. link: '${fenxurl}', // 分享链接
    68. imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
    69. success: function () {
    70. // 用户确认分享后执行的回调函数
    71. },
    72. cancel: function () {
    73. // 用户取消分享后执行的回调函数
    74. }
    75. });
    76. wx.onMenuShareWeibo({
    77. title: '计划书', // 分享标题
    78. desc: '保险让生活更美好!', // 分享描述
    79. link: '${fenxurl}', // 分享链接
    80. imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
    81. success: function () {
    82. // 用户确认分享后执行的回调函数
    83. },
    84. cancel: function () {
    85. // 用户取消分享后执行的回调函数
    86. }
    87. });
    88. wx.onMenuShareQZone({
    89. title: '计划书', // 分享标题
    90. desc: '保险让生活更美好!', // 分享描述
    91. link: '${fenxurl}', // 分享链接
    92. imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
    93. success: function () {
    94. // 用户确认分享后执行的回调函数
    95. },
    96. cancel: function () {
    97. // 用户取消分享后执行的回调函数
    98. }
    99. });
    100. });
    至此整个微信的整个分享开发完成,上面的这些js文件,都必须放在页面上。
    展开全文
  • 问题与需求:h5页面的内容在微信分享分享的内容无法定制,要自定义分享内容为该h5页面的标题,内容,图片等。  实现与排错:由于本人技术有限,基本都是参照网络上大神们提供的源码,在部分地方做了简单修改。...

                问题与需求:h5页面的内容在微信分享后分享的内容无法定制,要自定义分享内容为该h5页面的标题,内容,图片等。

                实现与排错:由于本人技术有限,基本都是参照网络上大神们提供的源码,在部分地方做了简单修改。感谢大神们的无私奉献!主要参考链接和实现代码如下:

                                        java开发微信分享到朋友圈功能  http://www.jb51.net/article/88690.htm
                                        微信公众平台开发:JS-SDK之分享功能整理(Java)http://blog.csdn.net/dcb_ripple/article/details/52066708

                                        实现】步骤一:参考微信公众平台的开发者文档https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html了解开发步骤

                                                    步骤二:为了描述方便,我先把h5页面的js代码贴出,再描述其实现所依赖的java代码。

    1.1h5页面的js代码

           h5页面:(获取该页面中的title-标题 discuss-内容 传入wx.config中实现分享内容的定制)                                  
          
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script>
        var url = window.location.href;
        var discuss ;
        var title ;
        var shareImgUrl="";
        var timestamp;
        var noncestr;
        var signature;
        var topicid = getUrlParameter('topicid');
        var userid =  getUrlParameter('userid');
        $.ajax({
            type: 'GET',
            url:  'topic/get?topicid=' + topicid+ '&userid=' + userid
        }).then(function successCallback(response) {
            var data = jsonToObj(response);
            discuss=data.data.discuss;
            title=data.data.title;
        }, function errorCallback(response) {
            console.log("error");
        });
    </script>
    <script src="js/weshare.js"></script>

           ps.由于我的页面用了angularjs,在js中如果通过document.getElementById拿值总是为空所以在js中再次使用了ajax向后台取值!!很影响性能的做法,在js中如何拿到angularjs渲染后的值呢?还希望有知道的朋友指点一下。
           weshare.js代码:
          
    
    //获取签名
    $.ajax({
        type: "GET",
        url: "wshare/getSignature",
        data:{url:url},
        success: function(data){
            console.log("success");
            var objData=JSON.parse(data);
            timestamp=objData.timestamp;
            noncestr=objData.noncestr;
            signature=objData.signature;
            console.log(objData);
            wxShare();
        },
        statusCode: {404: function(){
            alert('page not found');
        }}
    });
    function wxShare(){
        wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: 'wxca57e6589ccebff0', // 和获取Ticke的必须一样------必填,公众号的唯一标识
            timestamp:timestamp, // 必填,生成签名的时间戳
            nonceStr: noncestr, // 必填,生成签名的随机串
            signature: signature,// 必填,签名,见附录1
            jsApiList: [
                'onMenuShareAppMessage','onMenuShareTimeline','onMenuShareTimeline','onMenuShareQQ','onMenuShareQZone'
            ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        });
    }
    wx.ready(function(){
        //config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
        //config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关
        //接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    
        //----------“分享给朋友”
        wx.onMenuShareAppMessage({
            title:title, // 分享标题
            desc:discuss, // 分享描述
            link: url, // 分享链接
            imgUrl: shareImgUrl, // 分享图标
            success: function () {
                // 用户确认分享后执行的回调函数、
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
        //------------"分享到朋友圈"
        wx.onMenuShareTimeline({
            title: title, // 分享标题
            desc: discuss, // 分享描述
            link: url, // 分享链接
            imgUrl: shareImgUrl, // 分享图标
            type: '', // 分享类型,music、video或link,不填默认为link
            dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
            success: function () {
                // 用户确认分享后执行的回调函数、
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
        //-------------分享到QQ
        wx.onMenuShareQQ({
            title: title, // 分享标题
            desc: discuss, // 分享描述
            link: url, // 分享链接
            imgUrl: shareImgUrl, // 分享图标
            type: '', // 分享类型,music、video或link,不填默认为link
            dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
            success: function () {
                // 用户确认分享后执行的回调函数、
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
        //-------------分享到QQ空间
        wx.onMenuShareQZone({
            title: title, // 分享标题
            desc: discuss, // 分享描述
            link: url, // 分享链接
            imgUrl: shareImgUrl, // 分享图标
            type: '', // 分享类型,music、video或link,不填默认为link
            dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
            success: function () {
                // 用户确认分享后执行的回调函数、
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
    
    });
    wx.error(function(res){
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        console.log(res);
    });
    
    


    1.2java后台实现代码
          1.2.1 weixin.controller
          
    package com.weixin.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 com.weixin.util.WeixinUtil;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.google.gson.Gson;
    import com.weixin.model.Ticket;
    import com.weixin.util.GetRandomStr;
    import com.weixin.util.SignatureBean;
    
    
    
    /**
     * Created by Administrator on 2017/1/9.
     */
    @Controller
    @RequestMapping("/wshare")
    public class WeixinshareController {
    
            private static Ticket aticket = null;
    
            @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");
                //获取标签,并检查标签是否过期
                if(aticket==null){//第一次访问,标签不存在。
                    aticket = executeTicket(response,"1",url,format);
                    return null;
                }else{//标签存在,判断标签是否超时
                    String oldAcquiretime = aticket.getAcquiretime();
                    long difference=format.parse(format.format(new Date())).getTime()-format.parse(oldAcquiretime).getTime();
                    if(difference>7100000){//标签超时,重新到微信服务器请求标签超时时间为7200秒(7200000毫秒)
                        aticket = 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传给客户端***
                         */
                        System.out.print("ticket:"+aticket.getTicket());
                        String signature = signature(aticket.getTicket(),aticket.getTimestamp(),aticket.getNoncestr(),url);
                        SignatureBean signatureBean = new SignatureBean();
                        signatureBean.setNoncestr(aticket.getNoncestr());
                        signatureBean.setSignature(signature);
                        signatureBean.setTimestamp(aticket.getTimestamp());
                        signatureBean.setUrl(url);
                        response.setContentType("text/html;charset=UTF-8");
                        response.getWriter().print(new Gson().toJson(signatureBean));
                        return null;
                    }
                }
    
    
            }
            /**
             更新和获取ticket的方法,因为用的solr所以更新和新增是一样的ID无则添加,有则更新
             */
            public Ticket 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=wxca57e6589ccebff0&secret=b7d7c5df24644563be32bd84b90c8bf6";
                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是写死的 20160114wiimediamrylsong1152
                String acquiretime = format.format(new Date());
                ticket.setTid("20160114wiimediamrylsong1152");
                ticket.setAcquiretime(acquiretime);
                ticket.setTimestamp(timestamp);
                ticket.setNoncestr(noncestr);
    
                /**
                 * 注意事项
                 * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
                 * 2.签名用的url必须是调用JS接口页面的完整URL。
                 * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
                 *
                 *根据第1点要求   signature 配置的时候很容易出错,需要把生成 Ticket的 noncestr和 timestamp传给客户端*
                 */
    
                String signature = signature(t,timestamp,noncestr,url);
                System.out.print("ticket: "+t);
                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));
    
                return ticket;
            }
    
            /**
             *
             *

    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; } } }
           原大神的实现中是将Ticket存入数据库中,但是考虑到TicketId已写死,Ticket只有一条数据,存入数据库,再从数据库中取值新等过于麻烦,故将Ticket作为static变量。第一次访问时创建,超时时给他赋新值。
          1.2.2weixin.util
          {CSDN:CODE:2126562
         
    package com.weixin.util;
    
    /**
     * Created by Administrator on 2017/1/9.
     */
    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;
        }
    
    }
    

         
    package com.weixin.util;
    
    import java.util.Random;
    
    /**
     * Created by Administrator on 2017/1/9.
     * 获取随机字符串
     */
    
    public class GetRandomStr {
        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();
        }
    }
    
      
         
    package com.weixin.util;
    
    import javax.net.ssl.X509TrustManager;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    /**
     * Created by Administrator on 2017/1/10.
     */
    public class MyX509TrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
    
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
    
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
    

          ps.因为大神的注释写的很清楚,拉入我的项目中是可用滴,当然关于这个MyX509TrustManager我也不懂,百度之后还是不知道应该信任哪些证书,然后,干脆什么都没改,信任全部。当然网上也有很多不是通过Https请求的,然而根据微信现在的规定,好像都需要Https请求了。对于这个MyX509TrustManager大家有什么好的实现欢迎指教。
          1.2.3weixin.model     
         
    package com.weixin.model;
    
    /**
     * Created by Administrator on 2017/1/9.
     */
    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;
        }
    }
    

          最后,由于是在项目下新开的包,别忘了在Application.java中加入
    @ComponentScan(basePackages = {"com.mzqadmin","com.baidu","com.weixin"})
          另外,调试时把debug:true如果debug:ok却始终无法完成定制,一定是你的js代码有问题,后台验证已经通过了,看看你的js代码里参数是否带“”什么的。别问我怎么知道的,低级错误害死人呐~
          以上,是我做微信分享功能参考和实现的所有代码,有很多不足之处,还希望各位看官不吝赐教。
         
       
                




          
          
                            

                                                    

                                                    
      


                                            

                                                            

                                       

                                     

    展开全文
  • 微信公众号自定义分享跟我们自己打开一些对应页面的分享还是有区别的。 首先,自定义链接分享可以我们去主动去分享这个页面,同时我们可以有针对性的加上标题、图片、信息描述等。我们在生活中常常能够看到分享的...

    微信公众号自定义分享跟我们自己打开一些对应页面的分享还是有区别的。
    首先,自定义链接分享可以我们去主动去分享这个页面,同时我们可以有针对性的加上标题、图片、信息描述等。我们在生活中常常能够看到分享的好多链接,尤其类似于电商活动这类的链接,会有很吸人眼球的描述和图片。这就设计到了自定义分享链接。
    现在的开发趋势现在也会来越偏轻量化,所以很多开发人员也需要有一定微信公众号开发经验。我把我在项目中遇到的问题和踩过的坑给大家展示一下,希望能够给大家有所帮助
    在开发之前,强烈建议大家首先需要去详细阅读微信企业号开发文档
    根据开发文档,我们可以按照其对应的步骤一部一部去操作
    1.首先,在页面引入对应js文件

    <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    

    2.利用config接口注入权限验证配置

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

    我们在做接口配置时可以在后台中配置好相对应的配置信息


    3.定义ready接口

    wx.ready(function(){
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    });
    

    4.设置自定义分享

    我们分享的所有操作时间都是定义在ready接口下的,其中我们首先需要把要分享的事件配置到config接口中的jsApiList中。
    PS:在这里我只做关于朋友圈和微信的分享,其他的分享操作请参考微信JSSDK开发文档

    // 朋友圈
    wx.onMenuShareTimeline({
        title: '', // 分享标题
        link: '', // 分享链接,该链接域名必须与当前企业的可信域名一致
        imgUrl: '', // 分享图标
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
    //微信好友
    wx.onMenuShareAppMessage({
        title: '', // 分享标题
        desc: '', // 分享描述
        link: '', // 分享链接,该链接域名必须与当前企业的可信域名一致
        imgUrl: '', // 分享图标
        type: '', // 分享类型,music、video或link,不填默认为link
        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
    

    注意:
    这里我们需要注意的是,分享的链接必须是与当前页面对应的公众号JS安全域名一致,否则将调用失败。
    这个JS安全域名是在公众号配置里去定义。若域名不在这个目录下,我们的自定义分享就会失效,分享的内容链接都是网页默认提供的。
    5.设置重定向跳转页面
    很多人会有疑问为什么要这样做。这是因为我分享的页面是位于公众号下的活动页面,需要被分享的用户在点击打开的时候微信公众号获取自己的相应信息并执行相对应的操作。那么之前我们分享的本页面不可以么?
    我们在获取到权限进入到活动页面的时候,实际上本页面是自己系统设定好的路径。而别的用户直接通过这个路径当然是微信是获取不到相应的信息。

    // 当前页面
    var redirect_uri = ####;    // 这是我们真正的网页链接
    // 我们真正需要用户授权获取用户信息的下面的链接
    var link = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=######&redirect_uri="+ redirect_uri +"&response_type=code&scope=snsapi_baseinfo&state=1#wechat_redirect";
    

    那么我们不可以在分享链接的时候就直接定义为第二个链接么?
    当然不可以!请参考第4条,链接必须是在JS安全域名下的,否则自定义链接分享失效。
    我的想法就是,我自定义的链接是在当前页面下的一个页面,但这个页面是空白页面,它的作用就是重定向到我需要给用户呈现的链接和对应功能。

    if($("#id").val() != null){
            	var redirect_uri = window.location.protocol + "//" + window.location.host + "/wechat/hs/activityInfo/toDetail?id=" + $("#id").val();
            	window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=#########&redirect_uri="+ redirect_uri +"&response_type=code&scope=snsapi_baseinfo&state=1#wechat_redirect";
            }
    

    当然,应该还有更好的方法去解决这个问题,如果大家会更好的思路或见解,欢迎大家留言讨论。

    展开全文
  • 今天下午突然听到群里有微信小程序工具更新了,文档也更新了不少内容. 顾不上吃冬至的饺子.我就冲进来了. 先说分享功能,目前真机尚不能调试.开发工具上可以看看效果.后续还会更新. Page()中加上如下代码后在右...

    今天下午突然听到群里有人说微信小程序工具更新了,文档也更新了不少内容.
    顾不上吃冬至的饺子.我就冲进来了.
    先说分享功能,目前真机尚不能调试.开发工具上可以看看效果.后续还会更新.
    分享

    API

    Page()中加上如下代码后在右上角就会出现三个小白点
    title:分享的标题.
    desc:分享一段描述.
    path:这个参数有点意思.以前在微信中的分享一般都是url.这里是当前页面这里应该是pages/index?id=123这里的id目前还不知道是什么.
    也就是说以后你可以在微信中像分享一个网页一样分享一个页面了.

    onShareAppMessage: function () {
        return {
          title: '微信小程序联盟',
          desc: '最具人气的小程序开发联盟!',
          path: '/page/user?id=123'
        }
      }

    分享参数用处:
    我这里没有用到路径后的参数,说个场景:参数是用户昵称,A分享了XXX小程序到微信群里,B点开小程序,弹个toast,”来自A的分享”.

    1. 微信小程序开发之五星评分
    2.微信小程序开发之大转盘 仿天猫超市抽奖
    3. 微信小程序之仿微信漂流瓶

    CSDN微信小程序开发专栏,欢迎关注!

    展开全文
  • 刚开始坑公众号开发,然后坑微信支付开发,然后坑小程序开发。我真的走不出来了。。。。关键还没办法。 今天给大家分享一下app的二次分享问题吧。 是不是挺好玩的。这个时候就说了为什么变成这个样子,因为他...
  • 因为业务需求,需要开发公众号网页朋友圈分享,类似以下阅读文章以后进行分享,需要带上小标题,简介,图标,要做成这样的话,就要做微信网页开发,目前有两种解决方案,一种是第三方开放平台 标题...
  • 微信开发的概念

    2019-12-03 23:23:16
    微信开发的概念 什么是微信开发 微信这个软件,提供了聊天、支付、分享、收藏等各种功能,同时用户基数庞大; 微信对外开放了很多接口和能力,程序员基于这些功能进行的二次开发,叫做微信开发 微信开放平台 微信...
  • 最近在做微信服务号开发,简单总结一下,便于自己学习积累和分享给大家: 环境介绍: Spring+ Spring MVC +Mybatis 开发语言: JAVA 微信公众平台的开发中,微信只公布了一个基于Http协议的接口和加解密的...
  • 微信开发之JSSDK调用

    2016-11-22 17:03:13
    由于项目需要,需要接触微信开发,并要调用微信的JS-SDK里面的接口。 因为经验缺乏,我百度一下关于微信开发的资料,但收集的资料都不尽人意。网上的主流的微信开发是采用PHP开发的,而本人学的Java。所以对PHP微信...
  • 时间2018年10月,吐槽下微信小程序,因为一些原因说不能在分享到群的时候获取群id,但是我在开发的时候明显说可以获取的(体验版),但是正式版一跑问题就来了,获取群id时得时不得,不得:不进分享成功后的回调方法...
  • 本片文章的主要内容:微信分享,包括分享到好友、分享到朋友圈。 解决方案: 使用原生微信提供的sdk及其解决方案 使用已有的轮子(github里找) 使用第三方,如极光推送等。 方案一 首先,来探讨一下第一种方案:...
  • 20180811写在前面的话 有很多遇到问题之后问我,结果大多数是因为配置问题,所以请详细阅读前面的配置步骤。 20181016注意事项 ...id=mp1421141115中的分享接口,需要修改接口名称和参数列表...
  • 微信分享方法,扫码

    2020-01-15 22:37:35
    一: 微信分享流程: ... 2, 好友点击分享的链接时,需要拿到帮助的openid, 此时需要用微信授权的方式拿到code. 通过code去微信获取信息。...3, 分享出去的链接带上活动id和发起的openid。 二: 微信生成...
  • 截止到2017年11月18号,微信小程序官方还尚未开放直接分享到朋友圈的能力,但是劳动人民的智慧是伟大的【狗头】 现在普遍的做法是,生成一张带有小程序码的图片,保存到用户相册,用户自行发布图片到朋友圈 我的...
  • 本课程是一个系列入门教程,目标是从 0 开始带领读者上手实战,课程以微信小程序的核心概念作为主线,介绍配置文件、页面样式文件、JavaScript 的基本知识并以指南针为例对基本知识进行扩展,另外加上开发工具的安装...
  • 微信公共平台和微博分享一样,也需要申请一个ID,来作为调起微信分享微信的唯一标识。 申请微信APPID可以到微信平台http://open.weixin.qq.com/app/list/?lang=zh_CN上申请。具体的申请流程网站上有很详细的...
  • 作为系列文章的第五篇,本文重点探讨数据采集层中的微信分享追踪系统。微信分享,早已成为移动互联网运营的主要方向之一,以Web H5页面(下面称之为微信海报)为载体,利用微信庞大的好友关系进行传播,实现宣传、...
  • 微信小程序 分享功能

    2018-01-10 13:52:56
    1、分享 可以分享小程序的任何一个页面给好友或群聊。注意是分享给好友或群聊,并没有分享到朋友圈。一方面微信在尝试流量分发方式,但同时又不愿意开放最大的流量入口。 开发文档:...
  • 目的:开发分享功能,将第三方APP中的文字、图片、视频、网页等内容分享到微信的联系或者朋友圈。 步骤: 1.到微信开放平台申请自己的APP,获取AppID。 地址:http://open.weixin.qq.com/ 2.到官网下载sdk相关...
1 2 3 4 5 ... 20
收藏数 17,420
精华内容 6,968
关键字:

微信开发怎么加入分享人id