一种nodejs的MVC框架
mvc会针对请求进行分发,分发一般有controller(针对模块),action(针对模块中的方法),args(请求的参数)。
1.先对http请求的url进行设置,解析url中的各种参数:
//config.js
var route = require('./route');
//针对ajax请求
route.map({
method:'get',
url: /^\/category/mailCategory/i,
controller: 'mailCategory',
action: 'getMailCategory'
});
//controller为空,针对页面,针对页面
route.map({
method: 'get',
url: /^\/$/i,
controller: '',
action: 'list.html'
});
server.js的入口:
exports.runServer = function(port){
port = port || 10088;
/*
function(req,res){}它将会自动加入到 'request' 事件的监听队列。
它是http.IncomingMessage的一个实例。
*/
var server = http.createServer(function(req, res){
var _postData = '';
//on用于添加一个监听函数到一个特定的事件
req.on('data', function(chunk)
{
_postData += chunk;
})
.on('end', function()
{
req.post = querystring.parse(_postData);
handlerRequest(req, res);
});
}).listen(port); //程序运行的入口
console.log('Server running at http://180.150.189.25:'+ 10088 +'/');
};
当接收完请求的URL之后,执行handlerRequest(req, res);
/**
* 所有请求的统一入口
*/
var handlerRequest = function(req, res){
//通过route来获取controller和action信息
var actionInfo = route.getActionInfo(req.url, req.method);
//如果route中有匹配的action,则分发给对应的action
if(actionInfo.action){
var controller = actionInfo.controller;
//直接跳转页面
if(controller == ""){
viewEngine.forward(req, res, actionInfo.action);
return;
}
//加载action
if(controller[actionInfo.action]){
var ct = new controllerContext(req, res);
//如果是post请求,从重新设置参数
if(req.method.toLowerCase() == "post"){
actionInfo.args = req.post;
}
//通过apply将controller的上下文对象传递给action,路径转化就在这里。
controller[actionInfo.action].call(ct, actionInfo.args);
}else{
handler500(req, res, 'Error: controller "' + actionInfo.controller + '" without action "' + actionInfo.action + '"')
}
}else{
//如果route没有匹配到,则当作静态文件处理
staticFileServer(req, res);
}
};
viewEngine.forward代码如下:
var staticFileServer = function(req, res, filePath){
if(!filePath){
filePath = path.join(__dirname, config.staticFileDir, url.parse(req.url).pathname);
}
fs.exists(filePath, function(exists) {
if(!exists) {
//目录不存在的情况
handler404(req, res);
return;
}
var raw = fs.createReadStream(filePath);
var ext = path.extname(filePath);
ext = ext ? ext.slice(1) : 'html';
var acceptEncoding = req.headers['accept-encoding'];
var head = {'Content-Type': contentTypes[ext] || 'text/html'};
if (!acceptEncoding) {
acceptEncoding = '';
}
//根据请求头部信息,返回相应的数据
if(acceptEncoding.match(/\bgzip\b/)) {
head["content-encoding"] = "gzip";
res.writeHead(200, head);
raw.pipe(zlib.createGzip()).pipe(res);
}else if (acceptEncoding.match(/\bdeflate\b/)) {
head["content-encoding"] = "deflate";
res.writeHead(200, head);
raw.pipe(zlib.createDeflate()).pipe(res);
} else {
res.writeHead(200, head);
raw.pipe(res);
}
});
};
ct的上下文如下:
//controller的上下文对象
var controllerContext = function(req, res){
this.req = req;
this.res = res;
this.dbPool = dbPool;
this.contextPath = __dirname;
this.handler404 = handler404;
this.handler500 = handler500;
};
2.controller
通过上面的转发就可以把URL与module中的方法映射起来,我们写方法就可以按照模块来写了,例如mailCategory中的getMailCategory的方法如下:
在src模块中的action模块的MailCategory.js中:
/*MailCategory.js,提供两个action
getMailList 和 getMailCategory
*/
exports.getMailList = function(args){
var context = this;
var result = {errCode: 0, msg: 'success', categoryId: categoryId, data:[]}; //参数校验
var categoryId = args.categoryId;
if(!categoryId){
emitter.emit("invalidCategoryId", result, context);
return false;
} /**
* 获取邮件栏目信息
* @param isList 1 只是返回栏目列表 0 返回栏目及模块信息
* @returns {errCode:0, msg:'success', data:[{id:'', name: '', alias: ''},...]}
* @returns {errCode:0, msg:'success', data: [{id:'', name:'', alias:'', modules:[{id:'', name:''}, ...]}]}
*/
exports.getMailCategory = function(args){
}
3.module
为controller层提供数据,直接与数据库连接,或者中间加一道缓存,例如redis。刚刚看到在映射的过程中,传递对象的成员
this.dbPool = dbPool;
它的定义如下:
dbManager = require('./src/utilities/DbManager');
//数据库链接池
var dbPool = dbManager.getPool();
DbManager.js封装了连接数据库,或者一个连接池的对象
//创建mysql数据库链接
var mysql = require('mysql');
//连接池
var dbConfig = {
host: '180.150.189.25',
port: '3306',
user: 'iyy',
password: 'iyy@2015',
database: 'anthony',
connectionLimit: 20 //连接池最大连接数
//waitForConnections: false
} //从数据库获取一个链接
exports.getConnection = function(){
return mysql.createConnection(dbConfig);
} exports.getPool = function(){
var pool = mysql.createPool(dbConfig);
return pool;
}
这样就可以在controller模块中直接操作数据库,如下:
context.dbPool.getConnection(function(err,connection){
if(err){
emitter.emit("connectFailed", result, context);
return false;
}
//可以进一步拆分到module中。
connection.query("delete from MailModule where id="+intDeleteId,function(err,res){
if(err) {
emitter.emit("queryFailed", result, context);
return false;
}
/*
emitter.on("success", function(result, context){
result.errCode = 0;
result.msg = "success";
var str='updateuserinfo_callback({"ret":2,"errmsg":"asdas"})';
context.renderJson(str);
});
*/
emitter.emit("success", result, context);
});
//释放链接
connection.end();
});
一种nodejs的MVC框架的更多相关文章
- 安装nodeJs静态服务器(NodeJs Express MVC 框架)
安装 NodeJs Express MVC 框架 新建项目文件夹 打开cmd 执行以下操作: 一.使用Express框架 1)安装express3 $: npm install -g ex ...
- 12种JavaScript MVC框架之比较
Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月的时间研究和比较了12种流行的JavaScript MVC框架,并在博客中总结了每种框架的优缺点,最终的结果是,Ember. ...
- Struts和SpringMVC两种MVC框架比较
基于Web的MVC framework在J2EE的世界内已是空前繁荣.TTS网站上几乎每隔一两个星期就会有新的MVC框架发布.目前比较好的MVC,老牌的有Struts.Webwork.新兴的MVC框架 ...
- 转:12种JavaScript MVC框架之比较
Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月的时间研究和比较了12种流行的JavaScript MVC框架,并在博客中总结了每种框架的优缺点,最终的结果是,Ember. ...
- javascript:12种JavaScript MVC框架之比较
Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月的时间研究和比较了12种流行的JavaScript MVC框架,并在博客中总结了每种框架的优缺点,最终的结果是,Ember. ...
- 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--目录(8/8 完结)
为什么要做这个 在使用nodejs开发过程中,总是发现需要做很多重复性的体力劳动,且因为自身是服务端程序员出身,感觉有一些服务端好的东西其实可以在nodejs上得到应用并能提高一些开发工作效率. 本系 ...
- [转]12种JavaScript MVC框架之比较
From : http://www.infoq.com/cn/news/2012/05/js-mvc-framework/ Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月 ...
- 两种MVC框架比较
基于Web的MVC framework在J2EE的世界内已是空前繁荣. TTS网站上几乎每隔一两个星期就会有新的MVC框架发布.目前比较好的MVC,老牌的有Struts.Webwork.新兴的MVC框 ...
- 【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--自动路由篇(1/8)【route】
文章目录 前情概要 在使用express框架开发的时候,每加一个请求,都在增加一条route请求规则,类似于下面的代码,很烦有木有! app.use('/myroute path', (req, re ...
随机推荐
- Eclipse运行内存溢出
VM arguments中添加如下: -Xms512m-Xmx1024m-XX:PermSize=256m-XX:MaxPermSize=256m-Xmn128m
- [转]Null value was assigned to a property of primitive type setter of"原因及解决方法
原文地址:http://blog.csdn.net/kevinzhangfei/article/details/6995316 在action请求数据的过程中报出"Null value wa ...
- 【转】一个DIV+CSS代码布局的简单导航条
原文地址:http://www.divcss5.com/shili/s731.shtml 简单的DIV CSS代码布局实现导航条 一个蓝色主题的导航条布局案例,本CSS小实例,采用DIV CSS实现. ...
- Entity Framework Code First (八)迁移 Migrations
创建初始模型和数据库 在开始使用迁移(Migrations)之前,我们需要一个 Project 和一个 Code First Model, 对于本文将使用典型的 Blog 和 Post 模型 创建一个 ...
- 8 继承-extends
面向对象的特征:继承,封装和多态 java 当中只支持单继承,不允许多继承 class Person { String name; int age; void eat() { System.out.p ...
- 在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例
在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例 (2012-03-13 10:12:48) 转载▼ public ActionResu ...
- JDK与Java SE/EE/ME的区别
1. Java SE(Java Platform,Standard Edition). Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用 ...
- Genymotion关于【启动后player.exe已停止运行】解决方案总结
1. 你硬盘空间不足,或是暂存区不够,请少执行一些程序或关掉一些p2p的程序,或是到控制面板卸载一些不必要的程序.最好的建议是定期进行硬盘清理,确保不浪费多余空间 ---以上来源(http://www ...
- dedecms \plus\guestbook.php SQL Injection Vul By \plus\guestbook\edit.inc.php
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 注射漏洞成功需要条件如下 . php magic_quotes_gpc= ...
- dedeCMS /data/mysql_error_trace.php DB error raised PHP Code Injection Via /include/dedesql.class.php Log FIle Without Access Validation
目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 dedecms采用面向对象封装的方式实现了功能操作的模块集中化,例如对于数据库管理 ...