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(); } }
如是要頁面上配置,看我上一篇微信開發公衆號