Jfinal极速开发微信系列教程(一)--------------Jfinal_weixin demo的使用分析
概述:
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 微信开发环境的配置
public class WeixinConfig extends JFinalConfig { /**
* 如果生产环境配置文件存在,则优先加载该配置,否则加载开发环境配置文件
* @param pro 生产环境配置文件
* @param dev 开发环境配置文件
*/
public void loadProp(String pro, String dev) {
try {
PropKit.use(pro);
}
catch (Exception e) {
PropKit.use(dev);
}
} public void configConstant(Constants me) {
loadProp("a_little_config_pro.txt", "a_little_config.txt");
me.setDevMode(PropKit.getBoolean("devMode", false)); // ApiConfigKit 设为开发模式可以在开发阶段输出请求交互的 xml 与 json 数据
ApiConfigKit.setDevMode(me.getDevMode());
} public void configRoute(Routes me) {
me.add("/msg", WeixinMsgController.class);
me.add("/api", WeixinApiController.class, "/api");
} public void configPlugin(Plugins me) {
// C3p0Plugin c3p0Plugin = new C3p0Plugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
// me.add(c3p0Plugin); // EhCachePlugin ecp = new EhCachePlugin();
// me.add(ecp);
} public void configInterceptor(Interceptors me) { } public void configHandler(Handlers me) { } public static void main(String[] args) {
JFinal.start("webapp", 80, "/", 5);
}
}
以上通过 configRoute 方法配置了访问路由 "/msg" 与 "/api"。项目启动后,在微信服以务器上配置 url:http://域名/msg 填写Token时需要与配置文件(a_little_config.txt)中的保持一次
2、WeixinMsgController 微信消息处理
package com.jfinal.weixin.demo; import com.jfinal.kit.PropKit;
import com.jfinal.log.Logger;
import com.jfinal.weixin.sdk.api.ApiConfig;
import com.jfinal.weixin.sdk.jfinal.MsgController;
import com.jfinal.weixin.sdk.msg.in.*;
import com.jfinal.weixin.sdk.msg.in.event.*;
import com.jfinal.weixin.sdk.msg.in.speech_recognition.InSpeechRecognitionResults;
import com.jfinal.weixin.sdk.msg.out.*; /**
* 将此 DemoController 在YourJFinalConfig 中注册路由,
* 并设置好weixin开发者中心的 URL 与 token ,使 URL 指向该
* DemoController 继承自父类 WeixinController 的 index
* 方法即可直接运行看效果,在此基础之上修改相关的方法即可进行实际项目开发
*/
public class WeixinMsgController extends MsgController { static Logger logger = Logger.getLogger(WeixinMsgController.class);
private static final String helpStr = "\t发送 help 可获得帮助,发送\"视频\" 可获取视频教程,发送 \"美女\" 可看美女,发送 music 可听音乐 ,发送新闻可看JFinal新版本消息。公众号功能持续完善中"; /**
* 如果要支持多公众账号,只需要在此返回各个公众号对应的 ApiConfig 对象即可
* 可以通过在请求 url 中挂参数来动态从数据库中获取 ApiConfig 属性值
*/
public ApiConfig getApiConfig() {
ApiConfig ac = new ApiConfig(); // 配置微信 API 相关常量
ac.setToken(PropKit.get("token"));
ac.setAppId(PropKit.get("appId"));
ac.setAppSecret(PropKit.get("appSecret")); /**
* 是否对消息进行加密,对应于微信平台的消息加解密方式:
* 1:true进行加密且必须配置 encodingAesKey
* 2:false采用明文模式,同时也支持混合模式
*/
ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
return ac;
} // protected void processInTextMsg(InTextMsg inTextMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inTextMsg);
// render(outCustomMsg);
// }
//
// @Override
// protected void processInVoiceMsg(InVoiceMsg inVoiceMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inVoiceMsg);
// render(outCustomMsg);
// }
//
// @Override
// protected void processInVideoMsg(InVideoMsg inVideoMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inVideoMsg);
// render(outCustomMsg);
// }
//
// @Override
// protected void processInShortVideoMsg(InShortVideoMsg inShortVideoMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inShortVideoMsg);
// render(outCustomMsg);
// }
//
// @Override
// protected void processInLocationMsg(InLocationMsg inLocationMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inLocationMsg);
// render(outCustomMsg);
// }
//
// @Override
// protected void processInLinkMsg(InLinkMsg inLinkMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inLinkMsg);
// render(outCustomMsg);
// }
//
// @Override
// protected void processInCustomEvent(InCustomEvent inCustomEvent)
// {
// logger.debug("测试方法:processInCustomEvent()");
// renderNull();
// }
//
// protected void processInImageMsg(InImageMsg inImageMsg)
// {
// //转发给多客服PC客户端
// OutCustomMsg outCustomMsg = new OutCustomMsg(inImageMsg);
// render(outCustomMsg);
// }
//
// /**
// * 实现父类抽方法,处理关注/取消关注消息
// */
// protected void processInFollowEvent(InFollowEvent inFollowEvent)
// {
// if (InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent()))
// {
// logger.debug("关注:" + inFollowEvent.getFromUserName());
// OutTextMsg outMsg = new OutTextMsg(inFollowEvent);
// outMsg.setContent("这是Jfinal-weixin测试服务</br>\r\n感谢您的关注");
// render(outMsg);
// }
// // 如果为取消关注事件,将无法接收到传回的信息
// if (InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent()))
// {
// logger.debug("取消关注:" + inFollowEvent.getFromUserName());
// }
// }
//
// @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());
// }
// }
//
// @Override
// protected void processInLocationEvent(InLocationEvent inLocationEvent)
// {
// logger.debug("发送地理位置事件:" + inLocationEvent.getFromUserName());
// OutTextMsg outMsg = new OutTextMsg(inLocationEvent);
// outMsg.setContent("地理位置是:" + inLocationEvent.getLatitude());
// render(outMsg);
// }
//
// @Override
// protected void processInMassEvent(InMassEvent inMassEvent)
// {
// logger.debug("测试方法:processInMassEvent()");
// renderNull();
// }
//
// /**
// * 实现父类抽方法,处理自定义菜单事件
// */
// protected void processInMenuEvent(InMenuEvent inMenuEvent)
// {
// logger.debug("菜单事件:" + inMenuEvent.getFromUserName());
// OutTextMsg outMsg = new OutTextMsg(inMenuEvent);
// outMsg.setContent("菜单事件内容是:" + inMenuEvent.getEventKey());
// render(outMsg);
// }
//
// @Override
// protected void processInSpeechRecognitionResults(InSpeechRecognitionResults inSpeechRecognitionResults)
// {
// logger.debug("语音识别事件:" + inSpeechRecognitionResults.getFromUserName());
// OutTextMsg outMsg = new OutTextMsg(inSpeechRecognitionResults);
// outMsg.setContent("语音识别内容是:" + inSpeechRecognitionResults.getRecognition());
// render(outMsg);
// }
//
// @Override
// protected void processInTemplateMsgEvent(InTemplateMsgEvent inTemplateMsgEvent)
// {
// logger.debug("测试方法:processInTemplateMsgEvent()");
// renderNull();
// } /**
* 实现父类抽方法,处理文本消息
* 本例子中根据消息中的不同文本内容分别做出了不同的响应,同时也是为了测试 jfinal weixin sdk的基本功能:
* 本方法仅测试了 OutTextMsg、OutNewsMsg、OutMusicMsg 三种类型的OutMsg,
* 其它类型的消息会在随后的方法中进行测试
*/
protected void processInTextMsg(InTextMsg inTextMsg) {
String msgContent = inTextMsg.getContent().trim();
// 帮助提示
if ("help".equalsIgnoreCase(msgContent) || "帮助".equals(msgContent)) {
OutTextMsg outMsg = new OutTextMsg(inTextMsg);
outMsg.setContent(helpStr);
render(outMsg);
}
// 图文消息测试
else if ("news".equalsIgnoreCase(msgContent) || "新闻".equalsIgnoreCase(msgContent)) {
OutNewsMsg outMsg = new OutNewsMsg(inTextMsg);
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");
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");
render(outMsg);
}
// 音乐消息测试
else if ("music".equalsIgnoreCase(msgContent) || "音乐".equals(msgContent)) {
OutMusicMsg outMsg = new OutMusicMsg(inTextMsg);
outMsg.setTitle("When The Stars Go Blue-Venke Knutson");
outMsg.setDescription("建议在 WIFI 环境下流畅欣赏此音乐");
outMsg.setMusicUrl("http://www.jfinal.com/When_The_Stars_Go_Blue-Venke_Knutson.mp3");
outMsg.setHqMusicUrl("http://www.jfinal.com/When_The_Stars_Go_Blue-Venke_Knutson.mp3");
outMsg.setFuncFlag(true);
render(outMsg);
}
else if ("美女".equalsIgnoreCase(msgContent)) {
OutNewsMsg outMsg = new OutNewsMsg(inTextMsg);
outMsg.addNews(
"javenlife 宝贝更新喽",
"javenlife 宝贝更新喽,我们只看美女 ^_^",
"https://mmbiz.qlogo.cn/mmbiz/ibHRiaZ9MRcUosol56OtHjVibWTK9opiaxsYTQHXuRwoib8YobOfqCbykp3ZSaEk8czAqdkAARU0OdKDtv34F5evFIQ/0?wx_fmt=jpeg",
"http://mp.weixin.qq.com/s?__biz=MzA4MDA2OTA0Mg==&mid=207820985&idx=1&sn=4ef9361e68495fc3ba1d2f7f2bca0511#rd"); render(outMsg);
}
// 其它文本消息直接返回原值 + 帮助提示
else {
renderOutTextMsg("\t文本消息已成功接收,内容为: " + inTextMsg.getContent() + "\n\n" + helpStr);
}
} /**
* 实现父类抽方法,处理图片消息
*/
protected void processInImageMsg(InImageMsg inImageMsg) {
OutImageMsg outMsg = new OutImageMsg(inImageMsg);
// 将刚发过来的图片再发回去
outMsg.setMediaId(inImageMsg.getMediaId());
render(outMsg);
} /**
* 实现父类抽方法,处理语音消息
*/
protected void processInVoiceMsg(InVoiceMsg inVoiceMsg) {
OutVoiceMsg outMsg = new OutVoiceMsg(inVoiceMsg);
// 将刚发过来的语音再发回去
outMsg.setMediaId(inVoiceMsg.getMediaId());
render(outMsg);
} /**
* 实现父类抽方法,处理视频消息
*/
protected void processInVideoMsg(InVideoMsg inVideoMsg) {
/* 腾讯 api 有 bug,无法回复视频消息,暂时回复文本消息代码测试
OutVideoMsg outMsg = new OutVideoMsg(inVideoMsg);
outMsg.setTitle("OutVideoMsg 发送");
outMsg.setDescription("刚刚发来的视频再发回去");
// 将刚发过来的视频再发回去,经测试证明是腾讯官方的 api 有 bug,待 api bug 却除后再试
outMsg.setMediaId(inVideoMsg.getMediaId());
render(outMsg);
*/
OutTextMsg outMsg = new OutTextMsg(inVideoMsg);
outMsg.setContent("\t视频消息已成功接收,该视频的 mediaId 为: " + inVideoMsg.getMediaId());
render(outMsg);
} @Override
protected void processInShortVideoMsg(InShortVideoMsg inShortVideoMsg)
{
OutTextMsg outMsg = new OutTextMsg(inShortVideoMsg);
outMsg.setContent("\t视频消息已成功接收,该视频的 mediaId 为: " + inShortVideoMsg.getMediaId());
render(outMsg);
} /**
* 实现父类抽方法,处理地址位置消息
*/
protected void processInLocationMsg(InLocationMsg inLocationMsg) {
OutTextMsg outMsg = new OutTextMsg(inLocationMsg);
outMsg.setContent("已收到地理位置消息:" +
"\nlocation_X = " + inLocationMsg.getLocation_X() +
"\nlocation_Y = " + inLocationMsg.getLocation_Y() +
"\nscale = " + inLocationMsg.getScale() +
"\nlabel = " + inLocationMsg.getLabel());
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("感谢关注 JFinal Weixin 极速开发服务号,为您节约更多时间,去陪恋人、家人和朋友 :) \n\n\n " + helpStr);
// 如果为取消关注事件,将无法接收到传回的信息
render(outMsg);
} /**
* 实现父类抽方法,处理扫描带参数二维码事件
*/
protected void processInQrCodeEvent(InQrCodeEvent inQrCodeEvent) {
OutTextMsg outMsg = new OutTextMsg(inQrCodeEvent);
outMsg.setContent("processInQrCodeEvent() 方法测试成功");
render(outMsg);
} /**
* 实现父类抽方法,处理上报地理位置事件
*/
protected void processInLocationEvent(InLocationEvent inLocationEvent) {
OutTextMsg outMsg = new OutTextMsg(inLocationEvent);
outMsg.setContent("processInLocationEvent() 方法测试成功");
render(outMsg);
} @Override
protected void processInMassEvent(InMassEvent inMassEvent)
{
System.out.println("processInMassEvent() 方法测试成功");
} /**
* 实现父类抽方法,处理自定义菜单事件
*/
protected void processInMenuEvent(InMenuEvent inMenuEvent) {
renderOutTextMsg("processInMenuEvent() 方法测试成功");
} /**
* 实现父类抽方法,处理接收语音识别结果
*/
protected void processInSpeechRecognitionResults(InSpeechRecognitionResults inSpeechRecognitionResults) {
renderOutTextMsg("语音识别结果: " + inSpeechRecognitionResults.getRecognition());
} // 处理接收到的模板消息是否送达成功通知事件
protected void processInTemplateMsgEvent(InTemplateMsgEvent inTemplateMsgEvent) {
String status = inTemplateMsgEvent.getStatus();
renderOutTextMsg("模板消息是否接收成功:" + status);
}
}
3、WeixinApiController 微信接口处理
package com.jfinal.weixin.demo; import com.jfinal.kit.PropKit;
import com.jfinal.weixin.sdk.api.*;
import com.jfinal.weixin.sdk.jfinal.ApiController; public class WeixinApiController extends ApiController { /**
* 如果要支持多公众账号,只需要在此返回各个公众号对应的 ApiConfig 对象即可
* 可以通过在请求 url 中挂参数来动态从数据库中获取 ApiConfig 属性值
*/
public ApiConfig getApiConfig() {
ApiConfig ac = new ApiConfig(); // 配置微信 API 相关常量
ac.setToken(PropKit.get("token"));
ac.setAppId(PropKit.get("appId"));
ac.setAppSecret(PropKit.get("appSecret")); /**
* 是否对消息进行加密,对应于微信平台的消息加解密方式:
* 1:true进行加密且必须配置 encodingAesKey
* 2:false采用明文模式,同时也支持混合模式
*/
ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
return ac;
} /**
* 获取公众号菜单
*/
public void getMenu() {
ApiResult apiResult = MenuApi.getMenu();
if (apiResult.isSucceed())
renderText(apiResult.getJson());
else
renderText(apiResult.getErrorMsg());
} /**
* 创建菜单
*/
public void createMenu()
{
String str = "{\n" +
" \"button\": [\n" +
" {\n" +
" \"name\": \"进入理财\",\n" +
" \"url\": \"http://m.bajie8.com/bajie/enter\",\n" +
" \"type\": \"view\"\n" +
" },\n" +
" {\n" +
" \"name\": \"安全保障\",\n" +
" \"key\": \"112\",\n" +
"\t \"type\": \"click\"\n" +
" },\n" +
" {\n" +
"\t \"name\": \"使用帮助\",\n" +
"\t \"url\": \"http://m.bajie8.com/footer/cjwt\",\n" +
"\t \"type\": \"view\"\n" +
" }\n" +
" ]\n" +
"}";
ApiResult apiResult = MenuApi.createMenu(str);
if (apiResult.isSucceed())
renderText(apiResult.getJson());
else
renderText(apiResult.getErrorMsg());
} /**
* 获取公众号关注用户
*/
public void getFollowers()
{
ApiResult apiResult = UserApi.getFollows();
renderText(apiResult.getJson());
} /**
* 获取用户信息
*/
public void getUserInfo()
{
ApiResult apiResult = UserApi.getUserInfo("ohbweuNYB_heu_buiBWZtwgi4xzU");
renderText(apiResult.getJson());
} /**
* 发送模板消息
*/
public void sendMsg()
{
String str = " {\n" +
" \"touser\":\"ohbweuNYB_heu_buiBWZtwgi4xzU\",\n" +
" \"template_id\":\"9SIa8ph1403NEM3qk3z9-go-p4kBMeh-HGepQZVdA7w\",\n" +
" \"url\":\"http://www.sina.com\",\n" +
" \"topcolor\":\"#FF0000\",\n" +
" \"data\":{\n" +
" \"first\": {\n" +
" \"value\":\"恭喜你购买成功!\",\n" +
" \"color\":\"#173177\"\n" +
" },\n" +
" \"keyword1\":{\n" +
" \"value\":\"去哪儿网发的酒店红包(1个)\",\n" +
" \"color\":\"#173177\"\n" +
" },\n" +
" \"keyword2\":{\n" +
" \"value\":\"1元\",\n" +
" \"color\":\"#173177\"\n" +
" },\n" +
" \"remark\":{\n" +
" \"value\":\"欢迎再次购买!\",\n" +
" \"color\":\"#173177\"\n" +
" }\n" +
" }\n" +
" }";
ApiResult apiResult = TemplateMsgApi.send(str);
renderText(apiResult.getJson());
} /**
* 获取参数二维码
*/
public void getQrcode()
{
String str = "{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}";
ApiResult apiResult = QrcodeApi.create(str);
renderText(apiResult.getJson()); // String str = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"123\"}}}";
// ApiResult apiResult = QrcodeApi.create(str);
// renderText(apiResult.getJson());
} /**
* 长链接转成短链接
*/
public void getShorturl()
{
String str = "{\"action\":\"long2short\"," +
"\"long_url\":\"http://wap.koudaitong.com/v2/showcase/goods?alias=128wi9shh&spm=h56083&redirect_count=1\"}";
ApiResult apiResult = ShorturlApi.getShorturl(str);
renderText(apiResult.getJson());
} /**
* 获取客服聊天记录
*/
public void getRecord()
{
String str = "{\n" +
" \"endtime\" : 987654321,\n" +
" \"pageindex\" : 1,\n" +
" \"pagesize\" : 10,\n" +
" \"starttime\" : 123456789\n" +
" }";
ApiResult apiResult = CustomServiceApi.getRecord(str);
renderText(apiResult.getJson());
} /**
* 获取微信服务器IP地址
*/
public void getCallbackIp()
{
ApiResult apiResult = CallbackIpApi.getCallbackIp();
renderText(apiResult.getJson());
}
}
通过调用 MenuApi、UserApi 等 Api 的相关方法即可获取封装成 ApiResult 对象的结果,使用 render 系列方法即可快捷输出结果
四:运行项目测试
1、修改配置文件如图
例如:我的微信测试号
2、运行项目
在浏览器中输入:http://localhost/msg 测试 说明项目启动成功 欧耶........
3、微信开发模式接口配置信息
本地测试需要做外网的80端口映射
如果出现上图就配置成功的提示 到此就可以敬请的玩耍了....................
Jfinal极速开发微信系列教程(一)--------------Jfinal_weixin demo的使用分析的更多相关文章
- Jfinal极速开发微信系列教程(三)--------------对JSP的支持以及部署Tomcat运行异常问题
本文章主要解决以下问题: 1.Jfianl对JSP的支持2.Jfianl Maven项目部署到Tomcat,启动项目异常问题解决 第一个问题重现截图解决方案:1.在configConstant中添加视 ...
- Jfinal极速开发微信系列教程(二)--------------让微信公众平台通过80端口访问本机
概述: 微信公众平台要成为开发者,需要填写接口配置信息中的“URL”和“Token”这两项(参见:http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E ...
- 开发快平台(M302I小e开发板系列教程)
开发快平台(M302I小e开发板系列教程) 开发块平台ESP8266模块相关理解 一. M302I小e开发板源码注释,源码基于:v1.4.0.8-u34.zip 1. user_main.c /*** ...
- 小熊派IoT开发板系列教程正式发布——免费学习
[摘要] 小熊派开源社区针对小熊派IoT开发板首次规划了小熊派未来的系列教程.从基础到进阶的设计,可适应具有不同基础的开发者,通过该系列教程的学习,开发者能够轻松掌握IoT产品的开发.该系列教程包括单 ...
- 用c#开发微信 系列汇总
网上开发微信开发的教程很多,但c#相对较少.这里列出了我所有c#开发微信的文章,方便自己随时查阅. 一.基础知识 用c#开发微信(1)服务号的服务器配置和企业号的回调模式 - url接入 (源码下 ...
- iOS7入门开发全系列教程新地址
包括了系列1所有.系列2所有,系列3部分(进行中) 由于大家都知道的原因,换了github保存: https://github.com/eseedo/kidscoding 假设下载有问题能够留言,请在 ...
- jfinal极速开发
下载jfinal项目,上面都配置好了不用自己新建从头配置.https://jfinal.com/ idea打开项目 配置数据库 resources目录下demo-config-dev.txt # co ...
- JFinal极速开发实战-业务功能开发-通用表单验证器
提交表单数据时,需要经过前端的验证才能提交到后台,而后台的验证器再做一道数据的校验,成功之后才能进入action进行业务数据的处理. 在表单数据的验证中,数据类型的验证还是比较固定的.首先是对录入数据 ...
- 用c#开发微信 系列汇总 - z
http://www.cnblogs.com/txw1958/ http://www.cnblogs.com/fengwenit/p/4505062.html
随机推荐
- Android开发UI之GridLayout的使用
1.GridLayout 官网截图 GridLayout包含的属性如下: android:alignmentMode属性说明:当设置alignMargins,使视图的外边界之间进行校准.可以取以下值: ...
- Missing artifact com.sun:tools:jar:1.5.0的解决方案
今天在用maven的时候遇到一个问题pom.xml提示Missing artifact com.sun:tools:jar:1.5.0 试过改eclipse的eclipse.ini文件,也试过在ecl ...
- net remoting 服务器端订阅客户端(附源代码)
remoting 在分布式应用中逐渐在企业级应用发展开来,最初提出分布式应用,主要目的是为了降低服务器的压力,将耗性能的处理放在另外一个程序中,然后将计算结果发送到另外一个应用中.而remoting就 ...
- UVa 101 (模拟) The Blocks Problem
题意: 有n个木块及n个木块堆,初始状态是第i个木块在第i个木块堆上.对应有四种操作,然后输出最终状态. 分析: 用一个vector<int>模拟一个木块堆,进行相应操作即可. #incl ...
- ShareSDK 实现新浪微博分享(微信,QQ,新浪微博类似)
1 . 分享(前提是集成了sdk,配置好了Key),只要实现点击事件,调用shareSina(); ShareSDK.initSDK(this); private void shareSina() { ...
- WCF 服务调用RFC 出现异常
我在VS2010的WCF项目用connecter 3.0 调用 RFC 运行到 IDestinationConfiguration ID = new SAPConfig(); ...
- Gradle使用手册(二):项目结构
原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Using-sourceCompatibility-1. ...
- python运算符的优先级
运算符优先级 如果你有一个如2 + 3 * 4那样的表达式,是先做加法呢,还是先做乘法?我们的中学数学告诉我们应当先做乘法——这意味着乘法运算符的优先级高于加法运算符. 下面这个表给出Python的运 ...
- HDU 3642 Get The Treasury 线段树+分层扫描线
http://www.acmerblog.com/hdu-3642-get-the-treasury-6603.html 学习:三维就是把竖坐标离散化分层,每一层进行线段树二维面积并就好了
- HDU 5637 Transform 搜索
题意:bc round 74 div1 1002 中文题 分析(官方题解):注意到答案实际上只和s⊕t有关, bfs预处理下从0到xx的最短步数, 然后查询O(1)回答即可. #include < ...