java版微信分享开发+ssm框架

java版微信分享开发+ssm框架

简介

   本人第一次写csdn博客,表示这个编辑器第一次用户体验不是很好啊!不过功能还不错,日常吐槽一下。关于微信分享,微信官方文档给出了详细的开发流程,但是呢还是有许多坑,于是就想记录下来,方便自己回顾,也希望可以给看到的童鞋一些启发。

分享过程步骤简述


1.引入微信官方提供的JSSDK
  我们的项目是maven项目,可以直接在pom.xml添加项目依赖。如下
<!--微信SDK-->
<dependency>
  <groupId>com.github.wxpay</groupId>
  <artifactId>wxpay-sdk</artifactId>
  <version>0.0.3</version>
</dependency>
2.后台controller层开发

(1) 在前端页面加载的过程中,利用ajax从controller层获得需要向微信接口注入权限验证所需的配置信息。

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

根据配置信息,现在在后台将信息拼接好。

    @ResponseBody
    @RequestMapping("/coverAjax")
    public JSON coverAjax(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        //微信分享开始
        String appId = Constants.APP_ID;//取项目中配置的公众号id
        String secret = Constants.APP_SECRET;//取项目中配置的公众号密钥
        String domainAddr = Constants.DOMAIN_URL;//项目中配置的网站的域名
        String strs = request.getParameter("memberId"); //前台传递的参数
        String url = request.getParameter("hurs");   //前台传递的参数
        Map<String, String> map = new HashMap<String, String>();
        map.put("appid", appId);
        map.put("secret", secret);
        map.put("url", url);        //这个地址是传给页面使用
        request.setAttribute("shareUrl", url);
        session.setAttribute("shareUrl", url);
        System.out.println(url);
        //开始微信分享链接签名
        Map<String, String> params = wxService.weixinjsIntefaceSign(map, session);
        request.setAttribute("params", params);
        session.setAttribute("params", params);
        System.out.println(params);
        params.put("shareUrl", url);
        return (JSON) JSON.toJSON(params);
    }

(2)前端配置好微信的配置信息,同时调用微信分享朋友和朋友圈接口 (担心像我一样刚做项目的小白,我就把前端ajax页面全部提出来放在下面)

$(function(){
     var hurs = location.href.split('#')[0];
     $.ajax({
         type: "POST",
         url: "${pageContext.request.contextPath}/WxShare/coverAjax",
         data: {
             "hurs":hurs
         },//传递到后台中的参数
         dataType: "json",
         cache: false,
         success: function (data) {
             wxConfig(data);
         },
         error:function () {
             alert("错误")
         }
     });
 });
 function wxConfig(data) {
     wx.config({
          debug: false, // 开启调试模式
          appId: data.appId, // 必填,公众号的唯一标识
          timestamp: data.timestamp, // 必填,生成签名的时间戳
         nonceStr: data.noncestr, // 必填,生成签名的随机串
         signature: data.signature,// 必填,签名,见附录1
        jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage']// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
   });
    wx.ready(function () {
            wx.onMenuShareAppMessage({
            title: '${memberInfo.nickname}',
            desc: '${memberInfo.reInfo}',
            link: data.shareUrl,
            imgUrl: '${memberInfo.headImg}',
            success: function () {
                //alert("分享朋友成功");
            }
        });
        wx.onMenuShareTimeline({
            title: '${memberInfo.nickname}',
            link: data.shareUrl,
            imgUrl: '${memberInfo.headImg}',
            success: function () {
                //alert("分享朋友圈成功");
            }
        });
    });
}

注:分享的信息,title 和link 等信息 是在页面的后台包装好放在model里传给前端。

3.微信分享所需的签名算法

public Map<String, String> weixinjsIntefaceSign(Map<String, String> map,HttpSession session){
        //查看缓存数据是否存在
        Object cacheAccess_token = session.getAttribute("access_token_hl");
        Object cacheTicket = session.getAttribute("ticket");
        String cacheAccess_token_hl = (String) cacheAccess_token;
        String cacheTicket_hl = (String) cacheTicket;
        //取出来为空的话则说明cacheAccess_token缓存过期,重新获取
        if(null == cacheAccess_token_hl||cacheAccess_token_hl==""){
            //获取cacheAccess_token
            StringBuffer buffer = new StringBuffer();
            buffer.append("https://api.weixin.qq.com/cgi-bin/token?");
            buffer.append("grant_type=client_credential");
            buffer.append("&appid="+map.get("appid"));
            buffer.append("&secret="+map.get("secret"));
            System.out.println(buffer);
            try {
                String resultMsg = WxShareUtil.sendGet(buffer.toString(), "UTF-8");
                String jsons = resultMsg.substring(resultMsg.indexOf("{"), resultMsg.lastIndexOf("}") + 1);
                String[] result = jsons.split(",");
                String[] str1 = result[0].split(":");
                String str2 = str1[1].replace("\"","");
                cacheAccess_token_hl = str2;
                session.setAttribute("access_token_hl",cacheAccess_token_hl);
                         } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //取出来为空的话则说明cacheTicket缓存过期,重新获取
        if(null == cacheTicket_hl||cacheTicket_hl==""){
            获得jsapi_ticket
            StringBuffer buffer = new StringBuffer();
            buffer.append("https://api.weixin.qq.com/cgi-bin/ticket/getticket?");
            buffer.append("type=jsapi");
            buffer.append("&access_token="+session.getAttribute("access_token_hl"));
            String ticket = null;
            try {
                ticket = WxShareUtil.sendGet(buffer.toString(), "UTF-8");
                String jsons_t = ticket.substring(ticket.indexOf("{"), ticket.lastIndexOf("}") + 1);
                String[] result = jsons_t.split(",");
                String[] str1 = result[2].split(":");
                String str2 = str1[1].replace("\"","");
                cacheTicket_hl = str2;
               session.setAttribute("ticket",cacheTicket_hl);
                System.out.println("重新获取cacheTicket");
                System.out.println(ticket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //生成签名
        SortedMap<Object,Object> params = new TreeMap<Object,Object>();
        params.put("timestamp", Long.toString(new Date().getTime()/1000));
        params.put("noncestr", WXPayUtil.generateNonceStr());
        params.put("jsapi_ticket",cacheTicket_hl);
        params.put("url",map.get("url"));//url地址
        StringBuffer sb = new StringBuffer();
        Set es = params.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            sb.append(k + "=" + v + "&");
        }
        String  signStr = sb.toString().substring(0, sb.toString().length()-1);
        String sign = WxShareUtil.getSha1Sign(signStr);//签名
        Map<String, String> result = new HashMap<String,String>();
        result.put("timestamp",(String)params.get("timestamp"));
        result.put("noncestr", (String)params.get("noncestr"));
        result.put("signature", sign);
        result.put("appId",map.get("appid"));
        session.setMaxInactiveInterval(7200);
        return result;
    }

4.开发所需的工具类和遇到的坑


(1)常量类 Constants 就不展示出来了。分享的工具类代码如下: WxShareUtil

public class WxShareUtil {

    public static String sendGet(String url,String charset) throws IOException {
        //新建客户端
        HttpClient httpclient = new HttpClient();
        GetMethod getMethod = new GetMethod(url);
        httpclient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
        httpclient.executeMethod(getMethod);
        String responseMsg = getMethod.getResponseBodyAsString();
        return responseMsg;
    }

    public static String getSha1Sign(String decript) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            try {
                digest.update(decript.getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}

(2)开发微信分享遇到的坑
第一,微信分享,你需要将域名添加到微信公众平台上
JS接口安全域名
第二,你要将服务器的ip添加在微信公众平台的ip白名单里。
第三,分享页面的url,最好是动态获取当前页面的url,在传给后台,但是传的时候要做处理,使用 location.href.split(’#’)[0];去除多次分享后面的参数。
第四,在测试分享功能时,可以开启调试功能,然后在前端确保所需的配置参数都有。
第五,一定要将分享签名的token 和ticket 放在缓存里,微信是设置2个小时失效,所以 你需要设置两小时后 缓存清理,重新向微信申请获得access_token,注意,这个token和授权登录的token不一样。
最后:签名错误经常会碰到,耐心检查 一定会成功的。

5.写给大家和自己

感谢曾经写过微信分享的各位大佬,本人就是一个java后台开发菜鸟,基本都是面向百度编程,感谢他们的分享,让我顺利完成微信分享功能,如果代码中有一些很冗余甚至很智障的命名,请多担待认可,然后,如果有不是很懂的,也可以发邮件给我,我们可以talk一哈,以后,我还会继续写微信授权登录的java版功能开发和微信支付开发等等 ,希望自己能够逐渐成长为我很羡慕的大佬,加油!!!
最后,附上我的邮箱 3231394682@qq.com

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值