微信JS SDK Demo(Java版)

前几天在公司开发一个功能:微信分享,要求是分享的不是用户当前看到的这个页面,大家知道这在以前其实很简单的,但去年的最后一天,微信大力打击诱导分享、关注之后,以前的分享就不能用了,好在后来微信开放了JS SDK接口,可以满足这个需求,由于网上的例子写的都很简单,而且大多都是php,今天老夫就记录一下自己用Java如何实现的这个功能,窃以为比网上的很多Demo更具有实用性,大家在使用中如果有什么疑问,欢迎留言交流。废话到此为止,下面看看如何实现,当然了首先肯定要参考微信的文档:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html,其实这个文档上面说的已经比较详细了,但是距离真正使用当然还是有一定的距离的,在说老夫的代码之前,再多说一句,想调用微信的JS SDK,请确保你有一个经过微信认证的服务号,否则你是调用不了的,好,下面就看代码了: $(‘.share’).tap(function(){ var urlCurrery = window.location.href.split(‘#’)[0]; $.ajax({ type : "post", url : ‘share.do’, data : {‘urlCurrery’:urlCurrery}, success : function(data) { var dataObj = eval(data)[0]; var url =dataObj.url; var jsapi_ticket =dataObj.jsapi_ticket; var nonce_str =dataObj.nonceStr; var timestamp =dataObj.timestamp; var signature =dataObj.signature; wx.config({ debug: true, appId: appId;, timestamp: timestamp, nonceStr: nonce_str, signature: signature, jsApiList: [ ‘checkJsApi’, ‘onMenuShareTimeline’, ‘onMenuShareAppMessage’ ] }); wx.ready(function () { wx.onMenuShareAppMessage({ title: ‘分享测试’, desc: ‘分享测试’, link: ‘https://bridgeli.cn’, imgUrl: ”, success: function (res) { alert(‘已分享’); } }); wx.onMenuShareTimeline({ title: ‘分享测试’, link: ‘https://bridgeli.cn’, imgUrl: ”, success: function (res) { alert(‘已分享’); } }); alert(‘已注册获取“发送给朋友”状态事件’); alert(‘已注册获取“分享到朋友圈”状态事件’); }); } }); }); 经过分析微信的文档我们知道:如果想使用分享功能,那么请给分享注册事件,所以我们这里给文本中一个class为:share 的dom,绑定了分享事件,也就是说,我们想改变分享url,必须先点击一下该button,否则是不行的;另外通过文档里面的常见错误,我们可以知道,参与签名的url必须是动态获取的,如果不是,请通过ajax传到后台,为了强调这一点,微信专门用红色标注了,所以老夫在给class为share的button绑定事件的同时,将当前页面的 url (文中用:urlCurrery表示的)通用ajax传到后台 share.do 参与签名,我们一会再说后台怎么实现,接着分析前台代码,在经过后台签名之后,后台会传给前台一些数据,封装在data里面,这些就是我们需要的数据,相信通过微信的文档,所有人都能看得明白,就不多做解释了,在 wx.ready()方法里,老夫举了两个例子分别是分享给朋友和分享到朋友圈,其中的参数 link 就是你要分享的 url ,这一点很重要,这样就实现了我们分析的不是当前页面的 url 的需求,好了前台的说完了,下面就要看后台是怎么实现的了,这个其实很简单 ...

March 15, 2015 · 2 min · 350 words · Bridge Li

别人抢红包,程序猿来探讨微信红包的算法实现

曾经在公司写过一个类似于微信抢红包的功能,当时由于不会写,各种纠结,虽然最终实现了功能,但也仅仅是实现功能而已,像腾讯这么牛的公司肯定不是那样的,那么腾讯是怎么实现的呢?一直很好奇,但一直不得要领,今天偶然发现一篇文章,作者用很简单的算法,算是比较完美的解决了这个问题,说是完美,因为该算法满足了: 1、每个人都要能够领取到红包; 2、每个人领取到的红包金额总和=总金额; 3、每个人领取到的红包金额不等,但也不能差的太离谱,不然就没趣味; 4、算法一定要简单,不然对不起腾讯这个招牌; 但由于原文是Python写的(老夫的推测,因为老夫并不会Python,本文底部注有链接,感兴趣的可以看看),老夫改为由Java实现,当然介于水平,实现的可能并不好,写在这里算是抛砖引玉,如果有牛人写出来更好的,欢迎留言交流 package cn.bridgeli.hongbao; public class HongBao { public static void fenPei(double totalMoney, int totalPerson) { double min = 0.01; for (int i = 1; i < totalPerson; i++) { // 随机安全上限,同时扩大 100 倍 double safeTotal = ((totalMoney &#8211; (totalPerson &#8211; i) \* min) / (totalPerson &#8211; i)) \* 100; // 生成随机钱数 double money = Math.floor(Math.random() * safeTotal + 1.0) / 100; totalMoney -= money; System.out.println("第" + i + "个红包:" + money + " 元"); } System.out.println("第" + totalPerson + "个红包:" + roundDouble(totalMoney) + " 元"); } // 四舍五入 private static Double roundDouble(double val) { Double ret = null; try { // 2 表示保留两位小数 double factor = Math.pow(10, 2); ret = Math.floor(val * factor + 0.5) / factor; } catch (Exception e) { e.printStackTrace(); } return ret; } } 参考资料:http://mp.weixin.qq.com/s?__biz=MjM5OTA1MDUyMA==&mid=204349860&idx=2&sn=0a3433ff34c08dca5c47f7d97301e118#rd

February 25, 2015 · 1 min · 134 words · Bridge Li

反射的简单应用:解决微信开发中if-else过多的问题

前一段时间,闲着无聊玩微信开发,遇到一个问题:当关注者向公众号发送消息,请求一些服务时,由于是文本消息,所以当公众号拿到消息内容时,必须判断消息以什么打头,即: String content = requestMap.get("Content").trim(); if ("?".equals(content) || "?".equals(content)) { respContent = "您好,我是生活小助手,请根据提示,回复内容选择服务:nn1 回复“天气”获取天气帮助n2 回复“歌曲”获取歌曲帮助n3 回复“公交”获取歌曲帮助n4 回复“火车”获取歌曲帮助"; } else if (content.startsWith("歌曲")) { //TODO } else if (content.startsWith("天气")) { //TODO } else if (content.startsWith("物流")) { //TODO } else if (content.startsWith("公交")) { //TODO } else if (content.startsWith("火车")) { //TODO } else { respContent = "亲,很抱歉,由于功能还不够完善,尚不能处理您回复的信息,请回复“?”显示主菜单,获取帮助,有此给您带来的不便,还请见谅!"; } 来判断何种服务,调用具体的接口来处理,当你的功能越来越完善时,会导致if-else越来越多,多的会自己都搞不清了,另外这个方法也会越来越大,显然不是非常符合面向对象的单一职责原则。那么有没用一个比较好的方法来解决这个问题呢?我曾经的项目经理Zack曾经说过,上天不会这么惩罚一个后期维护代码的人,所以答案是勘定有,今天老夫就给大家带来一个解决方法,需要说明的是:这不是老夫的原创,是老夫研究捷微源码的找到的方法,老夫在捷微方法的基础上做了一些修改,所以先感谢捷微,感谢捷微的开发人员。最后需要说明的是,这个方法也不是很完善,如果有人参考的话,老样子,请做具体修改,但逻辑老夫保证不会有错。 @Override public BaseMessage handleText(String content, String fromUsername, String toUsername) { String respContent = null; BaseMessage baseMessage = null; if ("?".equals(content) || "?".equals(content)) { respContent = "您好,我是生活小助手,请根据提示,回复内容选择服务:nn1 回复“天气”获取天气帮助n2 回复“歌曲”获取歌曲帮助n3 回复“公交”获取公交帮助n4 回复“火车”获取火车帮助"; } else { List<WeixinExpandconfigEntity> weixinExpandconfigEntities = new ArrayList<WeixinExpandconfigEntity>(); boolean isFind = false;// 是否找到关键字信息 for (WeixinExpandconfigEntity weixinExpandconfigEntity : weixinExpandconfigEntities) { // 如果已经找到关键字并处理业务,结束循环。 if (isFind) { break;// 如果找到结束循环 } String[] keys = weixinExpandconfigEntity.getKeyword().split(","); for (String k : keys) { if (content.indexOf(k) != -1) { String className = weixinExpandconfigEntity.getClassname(); String returnType = weixinExpandconfigEntity.getReturnType(); KeyService keyService = null; try { keyService = (KeyService) Class.forName(className).newInstance(); baseMessage = (BaseMessage) Class.forName(returnType).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } keyService.excute(baseMessage, content.substring(2)); isFind = true; break; } } } } if (baseMessage == null) { TextMessage textMessage = new TextMessage(); textMessage.setContent(respContent); baseMessage = textMessage; } baseMessage.setToUserName(fromUsername); baseMessage.setFromUserName(toUsername); baseMessage.setCreateTime(new Date().getTime()); baseMessage.setFuncFlag(0); return baseMessage; }

September 15, 2014 · 1 min · 201 words · Bridge Li