jfinal wxing大家可能不太熟悉,他是jfinal框架(中国开源框架),用这个做微信公众号开发,非常快的,因为他已经把所有的微信的接口都集成里面了,我们主要是调用它的按口
要是你们PM要快点开发成功的话,我建议用这个框架。
框架下载地址:官网地址:http://www.jfinal.com/ 开源社区 http://git.oschina.net/jfinal/jfinal-weixin
我还是喜欢分成几步来成,
第一步配置:
1.我用的是IntelliJ IDEA 所以用的是maven搭的框架
<dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal-weixin</artifactId> <version>1.8</version> </dependency> <dependency> <groupId>com.squareup.okhttp</groupId> <artifactId>okhttp</artifactId> <version>2.7.5</version> </dependency>
2.
public class WeixinConfig extends JFinalConfig { public void configConstant(Constants me) {PropKit.use(”config_pro.txt“);
me.setDevMode(PropKit.getBoolean("devMode", false)); // ApiConfigKit ApiConfigKit.setDevMode(me.getDevMode());
//sql是否输出到日志
SqlReporter.setLogger(PropKit.getBoolean("SqlToLog", false));} public void configRoute(Routes me) { me.add("/msg", WeixinMsgController.class); me.add("/api", WeixinApiController.class, "/api"); } public void configPlugin(Plugins me) {
// 配置缓存插件 me.add(new EhCachePlugin());
//这里是配置数据库的 C3p0Plugin c3p0Plugin = new C3p0Plugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim()); me.add(c3p0Plugin); EhCachePlugin ecp = new EhCachePlugin(); me.add(ecp);
// 配置定时任务(这个主要是为了定时2个小时拿access_token)QuartzPlugin quartz = new QuartzPlugin(); quartz.setJobs("quartzJob.properties"); me.add(quartz); quartz.start();} public void configInterceptor(Interceptors me) { } public void configHandler(Handlers me) { } public static void main(String[] args) { JFinal.start("webapp", 80, "/", 5); }}
第二步写控制器
public class WeixinMsgController extends MsgControllerAdapter { public static String nearbyContent;// 附近 public static String location;// 地理位置114.037125,22.645319 public static String weahterContent; public String Regex = "[\\+ ~!@#%^-_=]?"; static Log logger = Log.getLog(WeixinMsgController.class); private static final String helpStr = " \n\n\t发送 help 可获得帮助,发送 \"美女\" 可看美女,发送 music 可听音乐 。\n\n" + "1、人脸识别" + "\n" + "2、在线翻译" + "\n" + "3、天气查询" + "\n" + "4、公交查询" + "\n" + "5、手机归属地查询" + "\n" + "6、身份证查询" + "\n" + "7、附近查询" + "\n" + "8、开发者模式" + "\n" + "9、QQ咨询" + "\n\n" + "10、获取资料密码" + "\n\n" ; /** * 如果要支持多公众账号,只需要在此返回各个公众号对应的 ApiConfig 对象即可 可以通过在请求 url 中挂参数来动态从数据库中获取 * ApiConfig 属性值 */ public ApiConfig getApiConfig() { return WeixinUtil.getApiConfig(); } /** * 实现父类抽方法,处理文本消息 本例子中根据消息中的不同文本内容分别做出了不同的响应,同时也是为了测试 jfinal weixin */ protected void processInTextMsg(InTextMsg inTextMsg) { String msgContent = inTextMsg.getContent().trim(); System.out.print("msgContent = " +msgContent); { // 帮助提示 if ("help".equalsIgnoreCase(msgContent) || "帮助".equals(msgContent)) { OutTextMsg outMsg = new OutTextMsg(inTextMsg); outMsg.setContent(helpStr); render(outMsg); } else if (msgContent.equals("1") || msgContent.equals("人脸识别")) { msgContent = "请发一张清晰的照片!" + WeixinUtil.emoji(0x1F4F7); renderOutTextMsg(msgContent); } else if (msgContent.equals("2") || msgContent.equals("在线翻译")) { renderOutTextMsg("在线翻译"); } else if (msgContent.startsWith("翻译")) { renderOutTextMsg("翻译"); } else if (msgContent.equals("3") || msgContent.equals("天气查询")) { renderOutTextMsg("天气查询"); } else if (msgContent.startsWith("天气")) { renderOutTextMsg("天气"); } else if (msgContent.equals("4") || msgContent.equals("公交查询")) { renderOutTextMsg("公交查询"); }else if (msgContent.equals("5") || msgContent.equals("手机归属地查询")) { renderOutTextMsg("手机归属地查询"); }else if (msgContent.equals("8") || "开发者模式".equalsIgnoreCase(msgContent)) { String url="开源中国中搜索Jfinal-weixin 或者Jfianl-qyweixin"; renderOutTextMsg(url); }else if (msgContent.equals("9") || "QQ咨询".equalsIgnoreCase(msgContent)) { String url="http://wpa.qq.com/msgrd?v=3&uin=572839485&site=qq&menu=yes"; String urlStr="<a href=\""+url+"\">点击咨询</a>"; renderOutTextMsg("QQ在线咨询"+urlStr); }else if (msgContent.equals("10") || "密码".contains(msgContent)) { String content="ngrok下载链接:http://pan.baidu.com/s/1dD99kGD 密码:jeyj"; renderOutTextMsg(content); }else if ("授权".equalsIgnoreCase(msgContent)) { String url= PropKit.get("domain")+"/oauth2/oauth"; String urlStr="<a href=\""+url+"\">点击我授权</a>"; renderOutTextMsg("授权地址"+urlStr); }else if ("jssdk".equalsIgnoreCase(msgContent)) { String url=PropKit.get("domain")+"/jssdk"; String urlStr="<a href=\""+url+"\">JSSDK</a>"; renderOutTextMsg("地址"+urlStr); } // 图文消息测试 else if ("11".equalsIgnoreCase(msgContent) || "12".equalsIgnoreCase(msgContent)) { OutNewsMsg outMsg = new OutNewsMsg(inTextMsg); News news=new News(); news.setPicUrl(this.getRequest().getSession().getServletContext().getRealPath("/")+ "\\images\\bealesf.jpg"); news.setUrl("http://blog.csdn.net/he3527/article/details/42583777"); news.setTitle("android 把assets 里面的图片文件输出到SD卡"); News newss=new News(); newss.setPicUrl(this.getRequest().getSession().getServletContext().getRealPath("/")+ "\\images\\bealesf.jpg"); newss.setUrl("http://blog.csdn.net/he3527/article/details/41517851"); newss.setTitle("HTTP返回代码 201 304 404 500等代表的含义"); News newsss=new News(); newsss.setPicUrl(this.getRequest().getSession().getServletContext().getRealPath("/")+ "\\images\\bealesf.jpg"); newsss.setUrl("http://blog.csdn.net/he3527/article/details/41517851"); newsss.setTitle("HTTP返回代码 201 304 404 500等代表的含义"); outMsg.addNews(news); outMsg.addNews(newss); outMsg.addNews(newsss); render(outMsg); } else if ("模板消息".equalsIgnoreCase(msgContent)) { ApiResult result = TemplateMsgApi.send(TemplateData.New() // 消息接收者 .setTouser(inTextMsg.getFromUserName()) // 模板id .setTemplate_id("tz1w-1fSN_Rzgj9_PjYuLU1EujvjPbtr1LL-_NtO6IM") .setTopcolor("#743A3A") .setUrl("http://img2.3lian.com/2014/f5/158/d/86.jpg") // 模板参数 .add("first", "您好,Javen,欢迎使用模版消息!!\n", "#999") .add("keyword1", "微信公众平台测试", "#999") .add("keyword2", "39.8元", "#999") .add("keyword3", "yyyy年MM月dd日 HH时mm分ss秒", "#999") .add("remark", "\n您的订单已提交,我们将尽快发货,祝生活愉快! 点击可以查看详细信息。", "#999") .build()); System.out.println(result.getJson()); renderNull(); } else { renderOutTextMsg("\t文本消息已成功接收,内容为: " + inTextMsg.getContent() + "\n\n" + helpStr); } } } /** * 实现父类抽方法,处理图片消息 */ protected void processInImageMsg(InImageMsg inImageMsg) {} /** * 实现父类抽方法,处理语音消息 */ protected void processInVoiceMsg(InVoiceMsg inVoiceMsg) { OutVoiceMsg outMsg = new OutVoiceMsg(inVoiceMsg); // 将刚发过来的语音再发回去 outMsg.setMediaId(inVoiceMsg.getMediaId()); render(outMsg); } /** * 实现父类抽方法,处理视频消息 */ protected void processInVideoMsg(InVideoMsg inVideoMsg) { OutTextMsg outMsg = new OutTextMsg(inVideoMsg); outMsg.setContent("\t视频消息已成功接收 " + inVideoMsg.getMediaId()); render(outMsg); } @Override protected void processInShortVideoMsg(InShortVideoMsg inShortVideoMsg) { OutTextMsg outMsg = new OutTextMsg(inShortVideoMsg); outMsg.setContent("\t视频消息已成功接收: " + inShortVideoMsg.getMediaId()); render(outMsg); } /** * 实现父类抽方法,处理地址位置消息 */ protected void processInLocationMsg(InLocationMsg inLocationMsg) { } @Override protected void processInQrCodeEvent(InQrCodeEvent inQrCodeEvent) { if (InQrCodeEvent.EVENT_INQRCODE_SUBSCRIBE.equals(inQrCodeEvent.getEvent())) { logger.debug("扫码未关注:" + inQrCodeEvent.getFromUserName()); OutTextMsg outMsg = new OutTextMsg(inQrCodeEvent); outMsg.setContent("感谢您的关注,二维码内容:" + inQrCodeEvent.getEventKey()); render(outMsg); } if (InQrCodeEvent.EVENT_INQRCODE_SCAN.equals(inQrCodeEvent.getEvent())) { logger.debug("扫码已关注:" + inQrCodeEvent.getFromUserName()); String key = inQrCodeEvent.getEventKey(); renderOutTextMsg(key); } } @Override protected void processInLocationEvent(InLocationEvent inLocationEvent) { OutTextMsg outMsg = new OutTextMsg(inLocationEvent); outMsg.setContent("地理位置是:\n" + inLocationEvent.getLatitude()+"\n"+inLocationEvent.getLongitude()); render(outMsg); } @Override protected void processInMassEvent(InMassEvent inMassEvent) { logger.debug("测试方法:processInMassEvent()"); renderNull(); } /** * 实现父类抽方法,处理自定义菜单事件 */ protected void processInMenuEvent(InMenuEvent inMenuEvent) { OutTextMsg outMsg = new OutTextMsg(inMenuEvent); outMsg.setContent("菜单事件内容是:" + inMenuEvent.getEventKey()); render(outMsg); } @Override protected void processInSpeechRecognitionResults(InSpeechRecognitionResults inSpeechRecognitionResults) { OutTextMsg outMsg = new OutTextMsg(inSpeechRecognitionResults); outMsg.setContent("语音识别内容是:" + inSpeechRecognitionResults.getRecognition()); render(outMsg); } /** * 实现父类抽方法,处理链接消息 特别注意:测试时需要发送我的收藏中的曾经收藏过的图文消息,直接发送链接地址会当做文本消息来发送 */ protected void processInLinkMsg(InLinkMsg inLinkMsg) { OutNewsMsg outMsg = new OutNewsMsg(inLinkMsg); outMsg.addNews("链接消息已成功接收", "链接使用图文消息的方式发回给你,还可以使用文本方式发回。点击图文消息可跳转到链接地址页面,是不是很好玩 :)", "http://mmbiz.qpic.cn/mmbiz/zz3Q6WSrzq1ibBkhSA1BibMuMxLuHIvUfiaGsK7CC4kIzeh178IYSHbYQ5eg9tVxgEcbegAu22Qhwgl5IhZFWWXUw/0", inLinkMsg.getUrl()); render(outMsg); } @Override protected void processInCustomEvent(InCustomEvent inCustomEvent) { System.out.println("processInCustomEvent() 方法测试成功"); } /** * 实现父类抽方法,处理关注/取消关注消息 */ protected void processInFollowEvent(InFollowEvent inFollowEvent) { OutTextMsg outMsg = new OutTextMsg(inFollowEvent); outMsg.setContent("感谢关注,节约更多时间,去陪恋人、家人和朋友 :) \n\n\n " + helpStr); // 如果为取消关注事件,将无法接收到传回的信息 render(outMsg); } // 处理接收到的模板消息是否送达成功通知事件 protected void processInTemplateMsgEvent(InTemplateMsgEvent inTemplateMsgEvent) { String status = inTemplateMsgEvent.getStatus(); renderOutTextMsg("模板消息是否接收成功:" + status); } @Override protected void processInShakearoundUserShakeEvent(InShakearoundUserShakeEvent inShakearoundUserShakeEvent) { OutTextMsg outMsg = new OutTextMsg(inShakearoundUserShakeEvent); outMsg.setContent("摇一摇周边设备信息" + inShakearoundUserShakeEvent.getUuid()); render(outMsg); }//"资质认证@Override protected void processInVerifySuccessEvent(InVerifySuccessEvent inVerifySuccessEvent) { logger.debug("资质认证成功" + inVerifySuccessEvent.getFromUserName()); OutTextMsg outMsg = new OutTextMsg(inVerifySuccessEvent); render(outMsg); }//"资质认证 @Override protected void processInVerifyFailEvent(InVerifyFailEvent inVerifyFailEvent) { OutTextMsg outMsg = new OutTextMsg(inVerifyFailEvent);outMsg.setContent("资质认证失败:" + inVerifyFailEvent.getFailReason());render(outMsg); }}
如上还有一个定时器:
job.trs.class= com.lgsw.common.util.AscTokendataJob #任务ID job.trs.id=1 #定时 120分钟一次 job.trs.cron=0 0/118 * * * ? #是否运行 job.trs.enable=true #----------------------------这是jifinal定时器的写法
public class AscTokendataJob implements Job { private static Logger log = LoggerFactory.getLogger(AscTokendataJob.class); /** * 初始化access_token配置并进行定时操作 */ public void init() { ApiConfig ac = new ApiConfig(); // 配置微信 API 相关常量 PropKit.use("config_pro.txt"); ac.setAppId(PropKit.get("appId","")); ac.setAppSecret(PropKit.get("appSecret","")); log.error("start init AscTokendataJob"); ApiConfigKit.setThreadLocalApiConfig(ac); AccessTokenApi.refreshAccessToken(); } public void execute(JobExecutionContext context) throws JobExecutionException{ init(); } public void start(){ init(); } }
如是要页面上配置,看我上一篇微信开发公众号