【原创】打造nodejs的一个简单MVC框架:ihttp-framework
2012-02-08 18:33
309 查看
我也是前段时间才接触到nodejs,感觉写起来挺爽的,大致学了下,就自己顺手写个简单(准确应该说是简陋)的MVC框架,当是练习了。
废话不多说,直接开上。
0.整体目录结构
![](http://pic002.cnblogs.com/images/2012/174735/2012020818350995.jpg)
大致说下,run.js是服务器监听入口,通过命令“node run”就可以开启服务了,server.js是HTTP服务器的创建代码,application.js则是MVC框架程序的入口,其他的就不一一介绍了。
1.搭建一个HTTP服务器
这部分就相当简单了,直接来官网的代码基本也可以搞定,我自己的代码如下:
这里不仅创建了一个HTTP服务器监听,并针对POST参数进行了处理。(注意我这里使用了exports,即构建了一个nodejs模块[关于模块,请参考相关nodejs教程],并将该类作为该模块的一个属性class,要引用该类的话,就使用像这样的代码:var Server = require('./server').class,后面的类定义也将遵循此格式。)在此,我们也得改变以往的过程式代码书写,转变思维为“事件驱动”型,熟悉前端JS/Jquery的童鞋都应该比较了解:
这种书写格式吧(即这些代码并不是立即就顺序执行的),当然,nodejs的高性能也在于此,“事件驱动”使得各个方面的IO都是无阻塞的,从而能够最大化利用资源。上面的代码通过on('data',function(){})来监听'data'事件,该事件即是浏览器向服务器POST数据时触发的事件,我们就只需要_postData += data;这样将数据一部分一部分保存到内存即可,一旦POST数据接收完毕,就会触发'end'事件,这时我们通过nodejs的内置库querystring来解析POST参数。(注意:这里仅仅是简单的解析了键值对(表单是application/x-www-form-urlencoded)这种形式的POST参数,如果有文件上传(表单是multipart/form-data)的话,那么要处理文件数据,格式就完全不一样了,具体可以参考:http://cnodejs.org/blog/?p=2207)。处理完毕后,我们将new appClass(req, res)创建一个application(即我们这里的MVC框架应用),用它来handle这些请求。
2.一个Application类(相当于MVC应用的入口)
这里Application的构造函数如下:
初始化完成后就直接调用了dispatcher函数,dispatcher函数主要的工作就是判断该请求是请求一个“动态资源”还是一个“静态资源(图片、css什么的)”(怎么判断的?这里我模仿apache的rewrite功能,使用正则来匹配,配置暂时写死在了core/route.js中),如果是请求“静态资源”,则我们直接读取该文件,然后输出。后面我们会着重讲“动态资源”(也就是请求动态网页了)。
3.完成C的部分
如果请求的是“动态资源”,那么就相当于是在调用我们的Controller部分了,这里我实现了一个Controller基类,所有的controller都将继承自这个基类,里面主要是一个vendor()方法,用于渲染网页。
至于如何定位controller及它下面的action,看看下面代码:
actionInfo是通过route.getActionInfo(this._req)解析而来,它包含了最终我们理解出来的controller和action以及GET参数,然后通过这些信息来定位具体的controller文件,初始化并执行它的action。
4.完成V的部分
这部分我主要实现了一个简陋的Template用于解析并渲染html模板,上面C的vendor函数就是调用的这个Template,而这个Template就相当简陋了,主要代码如下:
说白了就是一个正则替换,在html模板里面,我们就可以这样“{$var}”调用变量了:
是不是很简单:-)
5.完成M的部分
由于时间关系,这部分还没完成,主要也就是数据库连接与操作相关的了。。
结语
nodejs现在发展挺好的,相信你试用了之后,也会感觉到她的强大与舒适,js到时前后通吃了,呵呵。
上面项目的所有代码可以在http://code.google.com/p/ihttp-framework/ 获取,本人才疏学浅,有不对的地方还望提出、指点指点。
废话不多说,直接开上。
0.整体目录结构
![](http://pic002.cnblogs.com/images/2012/174735/2012020818350995.jpg)
大致说下,run.js是服务器监听入口,通过命令“node run”就可以开启服务了,server.js是HTTP服务器的创建代码,application.js则是MVC框架程序的入口,其他的就不一一介绍了。
1.搭建一个HTTP服务器
这部分就相当简单了,直接来官网的代码基本也可以搞定,我自己的代码如下:
exports.class = function(port){ this._port = port; } exports.class.prototype = { runApplication: function(appClass) { http.createServer(function(req, res) { console.log('[' + req.method + ']', req.url); var _postData = ''; //提取POST数据 req.on('data', function(data) { _postData += data; console.log('[Received]' + data.length); }); req.on('end', function() { //保存POST数据 req.post = querystring.parse(_postData); //交由dispatcher new appClass(req, res); }); }).listen(this._port); console.log('Server is running at port ' + this._port); } }
这里不仅创建了一个HTTP服务器监听,并针对POST参数进行了处理。(注意我这里使用了exports,即构建了一个nodejs模块[关于模块,请参考相关nodejs教程],并将该类作为该模块的一个属性class,要引用该类的话,就使用像这样的代码:var Server = require('./server').class,后面的类定义也将遵循此格式。)在此,我们也得改变以往的过程式代码书写,转变思维为“事件驱动”型,熟悉前端JS/Jquery的童鞋都应该比较了解:
req.on('data', function(data) { //TODO });
这种书写格式吧(即这些代码并不是立即就顺序执行的),当然,nodejs的高性能也在于此,“事件驱动”使得各个方面的IO都是无阻塞的,从而能够最大化利用资源。上面的代码通过on('data',function(){})来监听'data'事件,该事件即是浏览器向服务器POST数据时触发的事件,我们就只需要_postData += data;这样将数据一部分一部分保存到内存即可,一旦POST数据接收完毕,就会触发'end'事件,这时我们通过nodejs的内置库querystring来解析POST参数。(注意:这里仅仅是简单的解析了键值对(表单是application/x-www-form-urlencoded)这种形式的POST参数,如果有文件上传(表单是multipart/form-data)的话,那么要处理文件数据,格式就完全不一样了,具体可以参考:http://cnodejs.org/blog/?p=2207)。处理完毕后,我们将new appClass(req, res)创建一个application(即我们这里的MVC框架应用),用它来handle这些请求。
2.一个Application类(相当于MVC应用的入口)
这里Application的构造函数如下:
exports.class = function(req, res) { this._req = req, this._res = res; this.dispatcher(); }
初始化完成后就直接调用了dispatcher函数,dispatcher函数主要的工作就是判断该请求是请求一个“动态资源”还是一个“静态资源(图片、css什么的)”(怎么判断的?这里我模仿apache的rewrite功能,使用正则来匹配,配置暂时写死在了core/route.js中),如果是请求“静态资源”,则我们直接读取该文件,然后输出。后面我们会着重讲“动态资源”(也就是请求动态网页了)。
3.完成C的部分
如果请求的是“动态资源”,那么就相当于是在调用我们的Controller部分了,这里我实现了一个Controller基类,所有的controller都将继承自这个基类,里面主要是一个vendor()方法,用于渲染网页。
至于如何定位controller及它下面的action,看看下面代码:
var classPath = path.join(CONTROLLER_PATH, actionInfo.controller); var classRef = require(classPath).class; //类的一个引用 var c = new classRef(this._req, this._res); if (typeof(c[actionInfo.action]) != 'function') { actionInfo.action = config.defaultAction; //使用默认action if(typeof(c[actionInfo.action]) != 'function') { throw new Error('No callable action'); } }
actionInfo是通过route.getActionInfo(this._req)解析而来,它包含了最终我们理解出来的controller和action以及GET参数,然后通过这些信息来定位具体的controller文件,初始化并执行它的action。
4.完成V的部分
这部分我主要实现了一个简陋的Template用于解析并渲染html模板,上面C的vendor函数就是调用的这个Template,而这个Template就相当简陋了,主要代码如下:
var content = fs.readFileSync(file, 'utf8'); //替换变量 if(content) { result = content.replace(/\{\$(\w+)?\}/g, function() { return assign[arguments[1]]; //取第一个匹配项 即为 变量名 }); }
说白了就是一个正则替换,在html模板里面,我们就可以这样“{$var}”调用变量了:
<hr />This is:{$var1} <br />
是不是很简单:-)
5.完成M的部分
由于时间关系,这部分还没完成,主要也就是数据库连接与操作相关的了。。
结语
nodejs现在发展挺好的,相信你试用了之后,也会感觉到她的强大与舒适,js到时前后通吃了,呵呵。
上面项目的所有代码可以在http://code.google.com/p/ihttp-framework/ 获取,本人才疏学浅,有不对的地方还望提出、指点指点。
相关文章推荐
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 转载【Node.js简单介绍并实现一个简单的Web MVC框架】 http://cnodejs.org/blog/?p=342
- nodejs实现一个简单的 HTTP静态文件服务器(一)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)
- [原创]我的WCF之旅(1):创建一个简单的WCF程序
- 【IOS】利用ASIHTTPRequest 实现一个简单的登陆验证
- 一个简单的Golang实现的HTTP Proxy
- Netty构建一个简单的http服务
- 对于framework的目录结构分析以及简单的添加一个java层服务
- C++实现一个简单的双线程MVC框架
- nodejs模仿http请求组件nodegrass简单例子
- http-server:一个简单的零配置命令行的http服务器
- 打造一个简单的Java字节码反编译器