概述:

Jfinal_weixin已经出了有好一段时间了!一直在关注当中......最近工作上有需要到这个东西,所以,话了两个小时来看看这个东西,看完demo以后,豁然开朗,原理微信和一般的web项目什么的都是一样的!!所以,为了让后面的同学能够少走一些弯路,我觉得我很有必要把这个学习的过程记录下来,然后给大家进行参考,这样能够让更多的人完成这个微信项目的学习,从零开始学习。

在看此博客有什么不懂的地方可以在我的微信公众号或者微社区中交流。  微信开发交流群:114196246

如何开发微信?,这个东西大家可以去参考TX的那个微信开发文档,今天主要讲的都是Jfinal_weixin这个东西(如何创建一个WEB项目,如何获取Jfinal_weixin的开发包),也就是官网的那个demo。JFinal官网地址:http://www.jfinal.com/   开源社区 http://git.oschina.net/jfinal/jfinal-weixin

一:开源社区下载jfinal-weixin源码

下载解压的目录如下

二:将jfinal-weixin源码导入到IDE


三:分析源码如何使用jfinal-weixin

1、WeixinConfig  微信开发环境的配置

  1. public class WeixinConfig extends JFinalConfig {
  2.  
  3. /**
  4. * 如果生产环境配置文件存在,则优先加载该配置,否则加载开发环境配置文件
  5. * @param pro 生产环境配置文件
  6. * @param dev 开发环境配置文件
  7. */
  8. public void loadProp(String pro, String dev) {
  9. try {
  10. PropKit.use(pro);
  11. }
  12. catch (Exception e) {
  13. PropKit.use(dev);
  14. }
  15. }
  16.  
  17. public void configConstant(Constants me) {
  18. loadProp("a_little_config_pro.txt", "a_little_config.txt");
  19. me.setDevMode(PropKit.getBoolean("devMode", false));
  20.  
  21. // ApiConfigKit 设为开发模式可以在开发阶段输出请求交互的 xml 与 json 数据
  22. ApiConfigKit.setDevMode(me.getDevMode());
  23. }
  24.  
  25. public void configRoute(Routes me) {
  26. me.add("/msg", WeixinMsgController.class);
  27. me.add("/api", WeixinApiController.class, "/api");
  28. }
  29.  
  30. public void configPlugin(Plugins me) {
  31. // C3p0Plugin c3p0Plugin = new C3p0Plugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
  32. // me.add(c3p0Plugin);
  33.  
  34. // EhCachePlugin ecp = new EhCachePlugin();
  35. // me.add(ecp);
  36. }
  37.  
  38. public void configInterceptor(Interceptors me) {
  39.  
  40. }
  41.  
  42. public void configHandler(Handlers me) {
  43.  
  44. }
  45.  
  46. public static void main(String[] args) {
  47. JFinal.start("webapp", 80, "/", 5);
  48. }
  49. }

以上通过 configRoute 方法配置了访问路由 "/msg" 与 "/api"。项目启动后,在微信服以务器上配置 url:http://域名/msg  填写Token时需要与配置文件(a_little_config.txt)中的保持一次

2、WeixinMsgController 微信消息处理

  1. package com.jfinal.weixin.demo;
  2.  
  3. import com.jfinal.kit.PropKit;
  4. import com.jfinal.log.Logger;
  5. import com.jfinal.weixin.sdk.api.ApiConfig;
  6. import com.jfinal.weixin.sdk.jfinal.MsgController;
  7. import com.jfinal.weixin.sdk.msg.in.*;
  8. import com.jfinal.weixin.sdk.msg.in.event.*;
  9. import com.jfinal.weixin.sdk.msg.in.speech_recognition.InSpeechRecognitionResults;
  10. import com.jfinal.weixin.sdk.msg.out.*;
  11.  
  12. /**
  13. * 将此 DemoController 在YourJFinalConfig 中注册路由,
  14. * 并设置好weixin开发者中心的 URL 与 token ,使 URL 指向该
  15. * DemoController 继承自父类 WeixinController 的 index
  16. * 方法即可直接运行看效果,在此基础之上修改相关的方法即可进行实际项目开发
  17. */
  18. public class WeixinMsgController extends MsgController {
  19.  
  20. static Logger logger = Logger.getLogger(WeixinMsgController.class);
  21. private static final String helpStr = "\t发送 help 可获得帮助,发送\"视频\" 可获取视频教程,发送 \"美女\" 可看美女,发送 music 可听音乐 ,发送新闻可看JFinal新版本消息。公众号功能持续完善中";
  22.  
  23. /**
  24. * 如果要支持多公众账号,只需要在此返回各个公众号对应的 ApiConfig 对象即可
  25. * 可以通过在请求 url 中挂参数来动态从数据库中获取 ApiConfig 属性值
  26. */
  27. public ApiConfig getApiConfig() {
  28. ApiConfig ac = new ApiConfig();
  29.  
  30. // 配置微信 API 相关常量
  31. ac.setToken(PropKit.get("token"));
  32. ac.setAppId(PropKit.get("appId"));
  33. ac.setAppSecret(PropKit.get("appSecret"));
  34.  
  35. /**
  36. * 是否对消息进行加密,对应于微信平台的消息加解密方式:
  37. * 1:true进行加密且必须配置 encodingAesKey
  38. * 2:false采用明文模式,同时也支持混合模式
  39. */
  40. ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
  41. ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
  42. return ac;
  43. }
  44.  
  45. // protected void processInTextMsg(InTextMsg inTextMsg)
  46. // {
  47. // //转发给多客服PC客户端
  48. // OutCustomMsg outCustomMsg = new OutCustomMsg(inTextMsg);
  49. // render(outCustomMsg);
  50. // }
  51. //
  52. // @Override
  53. // protected void processInVoiceMsg(InVoiceMsg inVoiceMsg)
  54. // {
  55. // //转发给多客服PC客户端
  56. // OutCustomMsg outCustomMsg = new OutCustomMsg(inVoiceMsg);
  57. // render(outCustomMsg);
  58. // }
  59. //
  60. // @Override
  61. // protected void processInVideoMsg(InVideoMsg inVideoMsg)
  62. // {
  63. // //转发给多客服PC客户端
  64. // OutCustomMsg outCustomMsg = new OutCustomMsg(inVideoMsg);
  65. // render(outCustomMsg);
  66. // }
  67. //
  68. // @Override
  69. // protected void processInShortVideoMsg(InShortVideoMsg inShortVideoMsg)
  70. // {
  71. // //转发给多客服PC客户端
  72. // OutCustomMsg outCustomMsg = new OutCustomMsg(inShortVideoMsg);
  73. // render(outCustomMsg);
  74. // }
  75. //
  76. // @Override
  77. // protected void processInLocationMsg(InLocationMsg inLocationMsg)
  78. // {
  79. // //转发给多客服PC客户端
  80. // OutCustomMsg outCustomMsg = new OutCustomMsg(inLocationMsg);
  81. // render(outCustomMsg);
  82. // }
  83. //
  84. // @Override
  85. // protected void processInLinkMsg(InLinkMsg inLinkMsg)
  86. // {
  87. // //转发给多客服PC客户端
  88. // OutCustomMsg outCustomMsg = new OutCustomMsg(inLinkMsg);
  89. // render(outCustomMsg);
  90. // }
  91. //
  92. // @Override
  93. // protected void processInCustomEvent(InCustomEvent inCustomEvent)
  94. // {
  95. // logger.debug("测试方法:processInCustomEvent()");
  96. // renderNull();
  97. // }
  98. //
  99. // protected void processInImageMsg(InImageMsg inImageMsg)
  100. // {
  101. // //转发给多客服PC客户端
  102. // OutCustomMsg outCustomMsg = new OutCustomMsg(inImageMsg);
  103. // render(outCustomMsg);
  104. // }
  105. //
  106. // /**
  107. // * 实现父类抽方法,处理关注/取消关注消息
  108. // */
  109. // protected void processInFollowEvent(InFollowEvent inFollowEvent)
  110. // {
  111. // if (InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent()))
  112. // {
  113. // logger.debug("关注:" + inFollowEvent.getFromUserName());
  114. // OutTextMsg outMsg = new OutTextMsg(inFollowEvent);
  115. // outMsg.setContent("这是Jfinal-weixin测试服务</br>\r\n感谢您的关注");
  116. // render(outMsg);
  117. // }
  118. // // 如果为取消关注事件,将无法接收到传回的信息
  119. // if (InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent()))
  120. // {
  121. // logger.debug("取消关注:" + inFollowEvent.getFromUserName());
  122. // }
  123. // }
  124. //
  125. // @Override
  126. // protected void processInQrCodeEvent(InQrCodeEvent inQrCodeEvent)
  127. // {
  128. // if (InQrCodeEvent.EVENT_INQRCODE_SUBSCRIBE.equals(inQrCodeEvent.getEvent()))
  129. // {
  130. // logger.debug("扫码未关注:" + inQrCodeEvent.getFromUserName());
  131. // OutTextMsg outMsg = new OutTextMsg(inQrCodeEvent);
  132. // outMsg.setContent("感谢您的关注,二维码内容:" + inQrCodeEvent.getEventKey());
  133. // render(outMsg);
  134. // }
  135. // if (InQrCodeEvent.EVENT_INQRCODE_SCAN.equals(inQrCodeEvent.getEvent()))
  136. // {
  137. // logger.debug("扫码已关注:" + inQrCodeEvent.getFromUserName());
  138. // }
  139. // }
  140. //
  141. // @Override
  142. // protected void processInLocationEvent(InLocationEvent inLocationEvent)
  143. // {
  144. // logger.debug("发送地理位置事件:" + inLocationEvent.getFromUserName());
  145. // OutTextMsg outMsg = new OutTextMsg(inLocationEvent);
  146. // outMsg.setContent("地理位置是:" + inLocationEvent.getLatitude());
  147. // render(outMsg);
  148. // }
  149. //
  150. // @Override
  151. // protected void processInMassEvent(InMassEvent inMassEvent)
  152. // {
  153. // logger.debug("测试方法:processInMassEvent()");
  154. // renderNull();
  155. // }
  156. //
  157. // /**
  158. // * 实现父类抽方法,处理自定义菜单事件
  159. // */
  160. // protected void processInMenuEvent(InMenuEvent inMenuEvent)
  161. // {
  162. // logger.debug("菜单事件:" + inMenuEvent.getFromUserName());
  163. // OutTextMsg outMsg = new OutTextMsg(inMenuEvent);
  164. // outMsg.setContent("菜单事件内容是:" + inMenuEvent.getEventKey());
  165. // render(outMsg);
  166. // }
  167. //
  168. // @Override
  169. // protected void processInSpeechRecognitionResults(InSpeechRecognitionResults inSpeechRecognitionResults)
  170. // {
  171. // logger.debug("语音识别事件:" + inSpeechRecognitionResults.getFromUserName());
  172. // OutTextMsg outMsg = new OutTextMsg(inSpeechRecognitionResults);
  173. // outMsg.setContent("语音识别内容是:" + inSpeechRecognitionResults.getRecognition());
  174. // render(outMsg);
  175. // }
  176. //
  177. // @Override
  178. // protected void processInTemplateMsgEvent(InTemplateMsgEvent inTemplateMsgEvent)
  179. // {
  180. // logger.debug("测试方法:processInTemplateMsgEvent()");
  181. // renderNull();
  182. // }
  183.  
  184. /**
  185. * 实现父类抽方法,处理文本消息
  186. * 本例子中根据消息中的不同文本内容分别做出了不同的响应,同时也是为了测试 jfinal weixin sdk的基本功能:
  187. * 本方法仅测试了 OutTextMsg、OutNewsMsg、OutMusicMsg 三种类型的OutMsg,
  188. * 其它类型的消息会在随后的方法中进行测试
  189. */
  190. protected void processInTextMsg(InTextMsg inTextMsg) {
  191. String msgContent = inTextMsg.getContent().trim();
  192. // 帮助提示
  193. if ("help".equalsIgnoreCase(msgContent) || "帮助".equals(msgContent)) {
  194. OutTextMsg outMsg = new OutTextMsg(inTextMsg);
  195. outMsg.setContent(helpStr);
  196. render(outMsg);
  197. }
  198. // 图文消息测试
  199. else if ("news".equalsIgnoreCase(msgContent) || "新闻".equalsIgnoreCase(msgContent)) {
  200. OutNewsMsg outMsg = new OutNewsMsg(inTextMsg);
  201. outMsg.addNews("我的微信公众号javenlife", "Jfinal开发微信技术交流","https://mmbiz.qlogo.cn/mmbiz/ibHRiaZ9MRcUosol56OtHjVibWTK9opiaxsYTQHXuRwoib8YobOfqCbykp3ZSaEk8czAqdkAARU0OdKDtv34F5evFIQ/0?wx_fmt=jpeg", "http://mp.weixin.qq.com/s?__biz=MzA4MDA2OTA0Mg==&mid=208184833&idx=1&sn=d9e615e45902c3c72db6c24b65c4af3e#rd");
  202. outMsg.addNews("我的博客《智慧云端日记》", "现在就加入 JFinal 极速开发世界,节省更多时间去跟女友游山玩水 ^_^", "https://mmbiz.qlogo.cn/mmbiz/ibHRiaZ9MRcUosol56OtHjVibWTK9opiaxsY9tPDricojmV5xxuLJyibZJXMAdNOx1qbZFcic9SvsPF2fTUnSc9oQB1IQ/0?wx_fmt=jpeg","http://mp.weixin.qq.com/s?__biz=MzA4MDA2OTA0Mg==&mid=208413033&idx=1&sn=06e816e1b2905c46c9a81df0ac0b3bad#rd");
  203. render(outMsg);
  204. }
  205. // 音乐消息测试
  206. else if ("music".equalsIgnoreCase(msgContent) || "音乐".equals(msgContent)) {
  207. OutMusicMsg outMsg = new OutMusicMsg(inTextMsg);
  208. outMsg.setTitle("When The Stars Go Blue-Venke Knutson");
  209. outMsg.setDescription("建议在 WIFI 环境下流畅欣赏此音乐");
  210. outMsg.setMusicUrl("http://www.jfinal.com/When_The_Stars_Go_Blue-Venke_Knutson.mp3");
  211. outMsg.setHqMusicUrl("http://www.jfinal.com/When_The_Stars_Go_Blue-Venke_Knutson.mp3");
  212. outMsg.setFuncFlag(true);
  213. render(outMsg);
  214. }
  215. else if ("美女".equalsIgnoreCase(msgContent)) {
  216. OutNewsMsg outMsg = new OutNewsMsg(inTextMsg);
  217. outMsg.addNews(
  218. "javenlife 宝贝更新喽",
  219. "javenlife 宝贝更新喽,我们只看美女 ^_^",
  220. "https://mmbiz.qlogo.cn/mmbiz/ibHRiaZ9MRcUosol56OtHjVibWTK9opiaxsYTQHXuRwoib8YobOfqCbykp3ZSaEk8czAqdkAARU0OdKDtv34F5evFIQ/0?wx_fmt=jpeg",
  221. "http://mp.weixin.qq.com/s?__biz=MzA4MDA2OTA0Mg==&mid=207820985&idx=1&sn=4ef9361e68495fc3ba1d2f7f2bca0511#rd");
  222.  
  223. render(outMsg);
  224. }
  225. // 其它文本消息直接返回原值 + 帮助提示
  226. else {
  227. renderOutTextMsg("\t文本消息已成功接收,内容为: " + inTextMsg.getContent() + "\n\n" + helpStr);
  228. }
  229. }
  230.  
  231. /**
  232. * 实现父类抽方法,处理图片消息
  233. */
  234. protected void processInImageMsg(InImageMsg inImageMsg) {
  235. OutImageMsg outMsg = new OutImageMsg(inImageMsg);
  236. // 将刚发过来的图片再发回去
  237. outMsg.setMediaId(inImageMsg.getMediaId());
  238. render(outMsg);
  239. }
  240.  
  241. /**
  242. * 实现父类抽方法,处理语音消息
  243. */
  244. protected void processInVoiceMsg(InVoiceMsg inVoiceMsg) {
  245. OutVoiceMsg outMsg = new OutVoiceMsg(inVoiceMsg);
  246. // 将刚发过来的语音再发回去
  247. outMsg.setMediaId(inVoiceMsg.getMediaId());
  248. render(outMsg);
  249. }
  250.  
  251. /**
  252. * 实现父类抽方法,处理视频消息
  253. */
  254. protected void processInVideoMsg(InVideoMsg inVideoMsg) {
  255. /* 腾讯 api 有 bug,无法回复视频消息,暂时回复文本消息代码测试
  256. OutVideoMsg outMsg = new OutVideoMsg(inVideoMsg);
  257. outMsg.setTitle("OutVideoMsg 发送");
  258. outMsg.setDescription("刚刚发来的视频再发回去");
  259. // 将刚发过来的视频再发回去,经测试证明是腾讯官方的 api 有 bug,待 api bug 却除后再试
  260. outMsg.setMediaId(inVideoMsg.getMediaId());
  261. render(outMsg);
  262. */
  263. OutTextMsg outMsg = new OutTextMsg(inVideoMsg);
  264. outMsg.setContent("\t视频消息已成功接收,该视频的 mediaId 为: " + inVideoMsg.getMediaId());
  265. render(outMsg);
  266. }
  267.  
  268. @Override
  269. protected void processInShortVideoMsg(InShortVideoMsg inShortVideoMsg)
  270. {
  271. OutTextMsg outMsg = new OutTextMsg(inShortVideoMsg);
  272. outMsg.setContent("\t视频消息已成功接收,该视频的 mediaId 为: " + inShortVideoMsg.getMediaId());
  273. render(outMsg);
  274. }
  275.  
  276. /**
  277. * 实现父类抽方法,处理地址位置消息
  278. */
  279. protected void processInLocationMsg(InLocationMsg inLocationMsg) {
  280. OutTextMsg outMsg = new OutTextMsg(inLocationMsg);
  281. outMsg.setContent("已收到地理位置消息:" +
  282. "\nlocation_X = " + inLocationMsg.getLocation_X() +
  283. "\nlocation_Y = " + inLocationMsg.getLocation_Y() +
  284. "\nscale = " + inLocationMsg.getScale() +
  285. "\nlabel = " + inLocationMsg.getLabel());
  286. render(outMsg);
  287. }
  288.  
  289. /**
  290. * 实现父类抽方法,处理链接消息
  291. * 特别注意:测试时需要发送我的收藏中的曾经收藏过的图文消息,直接发送链接地址会当做文本消息来发送
  292. */
  293. protected void processInLinkMsg(InLinkMsg inLinkMsg) {
  294. OutNewsMsg outMsg = new OutNewsMsg(inLinkMsg);
  295. outMsg.addNews("链接消息已成功接收", "链接使用图文消息的方式发回给你,还可以使用文本方式发回。点击图文消息可跳转到链接地址页面,是不是很好玩 :)" , "http://mmbiz.qpic.cn/mmbiz/zz3Q6WSrzq1ibBkhSA1BibMuMxLuHIvUfiaGsK7CC4kIzeh178IYSHbYQ5eg9tVxgEcbegAu22Qhwgl5IhZFWWXUw/0", inLinkMsg.getUrl());
  296. render(outMsg);
  297. }
  298.  
  299. @Override
  300. protected void processInCustomEvent(InCustomEvent inCustomEvent)
  301. {
  302. System.out.println("processInCustomEvent() 方法测试成功");
  303. }
  304.  
  305. /**
  306. * 实现父类抽方法,处理关注/取消关注消息
  307. */
  308. protected void processInFollowEvent(InFollowEvent inFollowEvent) {
  309. OutTextMsg outMsg = new OutTextMsg(inFollowEvent);
  310. outMsg.setContent("感谢关注 JFinal Weixin 极速开发服务号,为您节约更多时间,去陪恋人、家人和朋友 :) \n\n\n " + helpStr);
  311. // 如果为取消关注事件,将无法接收到传回的信息
  312. render(outMsg);
  313. }
  314.  
  315. /**
  316. * 实现父类抽方法,处理扫描带参数二维码事件
  317. */
  318. protected void processInQrCodeEvent(InQrCodeEvent inQrCodeEvent) {
  319. OutTextMsg outMsg = new OutTextMsg(inQrCodeEvent);
  320. outMsg.setContent("processInQrCodeEvent() 方法测试成功");
  321. render(outMsg);
  322. }
  323.  
  324. /**
  325. * 实现父类抽方法,处理上报地理位置事件
  326. */
  327. protected void processInLocationEvent(InLocationEvent inLocationEvent) {
  328. OutTextMsg outMsg = new OutTextMsg(inLocationEvent);
  329. outMsg.setContent("processInLocationEvent() 方法测试成功");
  330. render(outMsg);
  331. }
  332.  
  333. @Override
  334. protected void processInMassEvent(InMassEvent inMassEvent)
  335. {
  336. System.out.println("processInMassEvent() 方法测试成功");
  337. }
  338.  
  339. /**
  340. * 实现父类抽方法,处理自定义菜单事件
  341. */
  342. protected void processInMenuEvent(InMenuEvent inMenuEvent) {
  343. renderOutTextMsg("processInMenuEvent() 方法测试成功");
  344. }
  345.  
  346. /**
  347. * 实现父类抽方法,处理接收语音识别结果
  348. */
  349. protected void processInSpeechRecognitionResults(InSpeechRecognitionResults inSpeechRecognitionResults) {
  350. renderOutTextMsg("语音识别结果: " + inSpeechRecognitionResults.getRecognition());
  351. }
  352.  
  353. // 处理接收到的模板消息是否送达成功通知事件
  354. protected void processInTemplateMsgEvent(InTemplateMsgEvent inTemplateMsgEvent) {
  355. String status = inTemplateMsgEvent.getStatus();
  356. renderOutTextMsg("模板消息是否接收成功:" + status);
  357. }
  358. }

3、WeixinApiController  微信接口处理

  1. package com.jfinal.weixin.demo;
  2.  
  3. import com.jfinal.kit.PropKit;
  4. import com.jfinal.weixin.sdk.api.*;
  5. import com.jfinal.weixin.sdk.jfinal.ApiController;
  6.  
  7. public class WeixinApiController extends ApiController {
  8.  
  9. /**
  10. * 如果要支持多公众账号,只需要在此返回各个公众号对应的 ApiConfig 对象即可
  11. * 可以通过在请求 url 中挂参数来动态从数据库中获取 ApiConfig 属性值
  12. */
  13. public ApiConfig getApiConfig() {
  14. ApiConfig ac = new ApiConfig();
  15.  
  16. // 配置微信 API 相关常量
  17. ac.setToken(PropKit.get("token"));
  18. ac.setAppId(PropKit.get("appId"));
  19. ac.setAppSecret(PropKit.get("appSecret"));
  20.  
  21. /**
  22. * 是否对消息进行加密,对应于微信平台的消息加解密方式:
  23. * 1:true进行加密且必须配置 encodingAesKey
  24. * 2:false采用明文模式,同时也支持混合模式
  25. */
  26. ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
  27. ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
  28. return ac;
  29. }
  30.  
  31. /**
  32. * 获取公众号菜单
  33. */
  34. public void getMenu() {
  35. ApiResult apiResult = MenuApi.getMenu();
  36. if (apiResult.isSucceed())
  37. renderText(apiResult.getJson());
  38. else
  39. renderText(apiResult.getErrorMsg());
  40. }
  41.  
  42. /**
  43. * 创建菜单
  44. */
  45. public void createMenu()
  46. {
  47. String str = "{\n" +
  48. " \"button\": [\n" +
  49. " {\n" +
  50. " \"name\": \"进入理财\",\n" +
  51. " \"url\": \"http://m.bajie8.com/bajie/enter\",\n" +
  52. " \"type\": \"view\"\n" +
  53. " },\n" +
  54. " {\n" +
  55. " \"name\": \"安全保障\",\n" +
  56. " \"key\": \"112\",\n" +
  57. "\t \"type\": \"click\"\n" +
  58. " },\n" +
  59. " {\n" +
  60. "\t \"name\": \"使用帮助\",\n" +
  61. "\t \"url\": \"http://m.bajie8.com/footer/cjwt\",\n" +
  62. "\t \"type\": \"view\"\n" +
  63. " }\n" +
  64. " ]\n" +
  65. "}";
  66. ApiResult apiResult = MenuApi.createMenu(str);
  67. if (apiResult.isSucceed())
  68. renderText(apiResult.getJson());
  69. else
  70. renderText(apiResult.getErrorMsg());
  71. }
  72.  
  73. /**
  74. * 获取公众号关注用户
  75. */
  76. public void getFollowers()
  77. {
  78. ApiResult apiResult = UserApi.getFollows();
  79. renderText(apiResult.getJson());
  80. }
  81.  
  82. /**
  83. * 获取用户信息
  84. */
  85. public void getUserInfo()
  86. {
  87. ApiResult apiResult = UserApi.getUserInfo("ohbweuNYB_heu_buiBWZtwgi4xzU");
  88. renderText(apiResult.getJson());
  89. }
  90.  
  91. /**
  92. * 发送模板消息
  93. */
  94. public void sendMsg()
  95. {
  96. String str = " {\n" +
  97. " \"touser\":\"ohbweuNYB_heu_buiBWZtwgi4xzU\",\n" +
  98. " \"template_id\":\"9SIa8ph1403NEM3qk3z9-go-p4kBMeh-HGepQZVdA7w\",\n" +
  99. " \"url\":\"http://www.sina.com\",\n" +
  100. " \"topcolor\":\"#FF0000\",\n" +
  101. " \"data\":{\n" +
  102. " \"first\": {\n" +
  103. " \"value\":\"恭喜你购买成功!\",\n" +
  104. " \"color\":\"#173177\"\n" +
  105. " },\n" +
  106. " \"keyword1\":{\n" +
  107. " \"value\":\"去哪儿网发的酒店红包(1个)\",\n" +
  108. " \"color\":\"#173177\"\n" +
  109. " },\n" +
  110. " \"keyword2\":{\n" +
  111. " \"value\":\"1元\",\n" +
  112. " \"color\":\"#173177\"\n" +
  113. " },\n" +
  114. " \"remark\":{\n" +
  115. " \"value\":\"欢迎再次购买!\",\n" +
  116. " \"color\":\"#173177\"\n" +
  117. " }\n" +
  118. " }\n" +
  119. " }";
  120. ApiResult apiResult = TemplateMsgApi.send(str);
  121. renderText(apiResult.getJson());
  122. }
  123.  
  124. /**
  125. * 获取参数二维码
  126. */
  127. public void getQrcode()
  128. {
  129. String str = "{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}";
  130. ApiResult apiResult = QrcodeApi.create(str);
  131. renderText(apiResult.getJson());
  132.  
  133. // String str = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"123\"}}}";
  134. // ApiResult apiResult = QrcodeApi.create(str);
  135. // renderText(apiResult.getJson());
  136. }
  137.  
  138. /**
  139. * 长链接转成短链接
  140. */
  141. public void getShorturl()
  142. {
  143. String str = "{\"action\":\"long2short\"," +
  144. "\"long_url\":\"http://wap.koudaitong.com/v2/showcase/goods?alias=128wi9shh&spm=h56083&redirect_count=1\"}";
  145. ApiResult apiResult = ShorturlApi.getShorturl(str);
  146. renderText(apiResult.getJson());
  147. }
  148.  
  149. /**
  150. * 获取客服聊天记录
  151. */
  152. public void getRecord()
  153. {
  154. String str = "{\n" +
  155. " \"endtime\" : 987654321,\n" +
  156. " \"pageindex\" : 1,\n" +
  157. " \"pagesize\" : 10,\n" +
  158. " \"starttime\" : 123456789\n" +
  159. " }";
  160. ApiResult apiResult = CustomServiceApi.getRecord(str);
  161. renderText(apiResult.getJson());
  162. }
  163.  
  164. /**
  165. * 获取微信服务器IP地址
  166. */
  167. public void getCallbackIp()
  168. {
  169. ApiResult apiResult = CallbackIpApi.getCallbackIp();
  170. renderText(apiResult.getJson());
  171. }
  172. }

通过调用 MenuApi、UserApi 等 Api 的相关方法即可获取封装成 ApiResult 对象的结果,使用 render 系列方法即可快捷输出结果

四:运行项目测试

1、修改配置文件如图

例如:我的微信测试号

2、运行项目

在浏览器中输入:http://localhost/msg 测试  说明项目启动成功  欧耶........

3、微信开发模式接口配置信息

本地测试需要做外网的80端口映射

   如果出现上图就配置成功的提示  到此就可以敬请的玩耍了....................

Jfinal极速开发微信系列教程(一)--------------Jfinal_weixin demo的使用分析的更多相关文章

  1. Jfinal极速开发微信系列教程(三)--------------对JSP的支持以及部署Tomcat运行异常问题

    本文章主要解决以下问题: 1.Jfianl对JSP的支持2.Jfianl Maven项目部署到Tomcat,启动项目异常问题解决 第一个问题重现截图解决方案:1.在configConstant中添加视 ...

  2. Jfinal极速开发微信系列教程(二)--------------让微信公众平台通过80端口访问本机

    概述: 微信公众平台要成为开发者,需要填写接口配置信息中的“URL”和“Token”这两项(参见:http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E ...

  3. 开发快平台(M302I小e开发板系列教程)

    开发快平台(M302I小e开发板系列教程) 开发块平台ESP8266模块相关理解 一. M302I小e开发板源码注释,源码基于:v1.4.0.8-u34.zip 1. user_main.c /*** ...

  4. 小熊派IoT开发板系列教程正式发布——免费学习

    [摘要] 小熊派开源社区针对小熊派IoT开发板首次规划了小熊派未来的系列教程.从基础到进阶的设计,可适应具有不同基础的开发者,通过该系列教程的学习,开发者能够轻松掌握IoT产品的开发.该系列教程包括单 ...

  5. 用c#开发微信 系列汇总

    网上开发微信开发的教程很多,但c#相对较少.这里列出了我所有c#开发微信的文章,方便自己随时查阅.   一.基础知识 用c#开发微信(1)服务号的服务器配置和企业号的回调模式 - url接入 (源码下 ...

  6. iOS7入门开发全系列教程新地址

    包括了系列1所有.系列2所有,系列3部分(进行中) 由于大家都知道的原因,换了github保存: https://github.com/eseedo/kidscoding 假设下载有问题能够留言,请在 ...

  7. jfinal极速开发

    下载jfinal项目,上面都配置好了不用自己新建从头配置.https://jfinal.com/ idea打开项目 配置数据库 resources目录下demo-config-dev.txt # co ...

  8. JFinal极速开发实战-业务功能开发-通用表单验证器

    提交表单数据时,需要经过前端的验证才能提交到后台,而后台的验证器再做一道数据的校验,成功之后才能进入action进行业务数据的处理. 在表单数据的验证中,数据类型的验证还是比较固定的.首先是对录入数据 ...

  9. 用c#开发微信 系列汇总 - z

    http://www.cnblogs.com/txw1958/ http://www.cnblogs.com/fengwenit/p/4505062.html

随机推荐

  1. Linux配置vpn

    配置如下

  2. struts采用JavaServlet/JSP技术,实现了基于Java EEWeb应用的MVC设计模式的应用框架

    今天我用Ecipse搭建Struts框架,并且使用Struts框架编写一个最简单的例子,相信读者能够很容易的明白. Struts是当今Java比较流行的三大框架之一,三大框架是Struts,sprin ...

  3. many-to-one和one-to-many的配置比较

    many-to-one配置: <many-to-one name="dailyCatalog" column="daily_catalog_id" cla ...

  4. jquery提示气泡

    <link href="css/manhua_hoverTips.css" type="text/css" rel="stylesheet&qu ...

  5. 深入分析Cookie的安全性问题

    Cookie的目的是为用户带来方便,为网站带来增值,一般情况下不会造成严重的安全威胁.Cookie文件不能作为代码执行,也不会传送病毒,它为用户所专有并只能由创建它的服务器来读取.另外,浏览器一般只允 ...

  6. SPOJ 962 Intergalactic Map (从A到B再到C的路线)

    [题意]在一个无向图中,一个人要从A点赶往B点,之后再赶往C点,且要求中途不能多次经过同一个点.问是否存在这样的路线.(3 <= N <= 30011, 1 <= M <= 5 ...

  7. 探秘Java虚拟机——内存管理与垃圾回收

    本文主要是基于Sun JDK 1.6 Garbage Collector(作者:毕玄)的整理与总结,原文请读者在网上搜索. 1.Java虚拟机运行时的数据区 2.常用的内存区域调节参数 -Xms:初始 ...

  8. Java [Leetcode 39]Combination Sum

    题目描述: Given a set of candidate numbers (C) and a target number (T), find all unique combinations in  ...

  9. 前端的小Demo——涉及keyCode

    以下是我的代码: <!doctype html> <html> <head> <meta charset="utf-8"> < ...

  10. MyEclipse10破解后将工程导成war包时报错

    MyEclipse10.7 破解后将工程导成war包时报错 : SECURITY ALERT:INTEGRITY CHECK ERROR     This product did not pass t ...