龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

Node.js后端框架设计构想(1)(2)

时间:2013-03-06 14:58来源:未知 作者:admin 点击:
分享到:
postData拦截器 mass.define(intercepters/postData,querystring,function(qs){ console.log(本模块用于取得POST请求过来的数据,并作为request.body而存在); returnmass.intercepter(functio

postData拦截器

  1. mass.define("intercepters/postData","querystring",function(qs){  
  2.     console.log("本模块用于取得POST请求过来的数据,并作为request.body而存在");  
  3.     return mass.intercepter(function(req,res){  
  4.         console.log("进入postData回调");  
  5.         reqreq.body = req.body || {};  
  6.         if ( req._body ||  /GET|HEAD/.test(req.method) || 'application/x-www-form-urlencoded' !== req.mime ){  
  7.             return true;  
  8.         }  
  9.         var buf = '';  
  10.         req.setEncoding('utf8');  
  11.         function buildBuffer(chunk){  
  12.             buf += chunk  
  13.         }  
  14.         req.on('data', buildBuffer);  
  15.         req.once('end',function(){  
  16.             try {  
  17.                 if(buf != ""){  
  18.                     req.body = qs.parse(buf);  
  19.                     req._body = true;  
  20.                 }  
  21.                 req.emit("next_intercepter",req,res)  
  22.             } catch (err){  
  23.                 req.emit("next_intercepter",req,res,err)  
  24.             }finally{  
  25.                 req.removeListener("data",buildBuffer)  
  26.             }  
  27.         })  
  28.     });  
  29. }); 

query拦截器

  1. mass.define("intercepters/query","querystring,url",function(qs,URL){  
  2.     console.log("本模块用于取得URL的参数并转为一个对象,作为request.query而存在");  
  3.     return mass.intercepter(function(req, res){  
  4.         req.query = ~req.url.indexOf('?')  
  5.         ? qs.parse(URL.parse(req.url).query)  
  6.         : {};  
  7.         return true;  
  8.     })  
  9. }) 

methodOverride拦截器

  1. mass.define("intercepters/methodOverride",function(){  
  2.     console.log("本模块用于校正method属性");  
  3.     var methods = {  
  4.         "PUT":"PUT",  
  5.         "DELETE":"DELETE"  
  6.     },  
  7.     method = mass.configs.method || "_method";  
  8.     return mass.intercepter(function(req, res){  
  9.         reqreq.originalMethod = req.method;  
  10.         var defaultMethod = req.method === "HEAD" ? "GET" : req.method;  
  11.         var _method = req.body ? req.body[method] : req.headers['x-http-method-override']  
  12.         _method = (_method || "").toUpperCase();  
  13.         req.method = methods[_method] || defaultMethod;  
  14.         if(req.body){  
  15.             delete req.body[method];  
  16.         }  
  17.         return true;  
  18.     })  
  19. }) 

json拦截器

  1. mass.define("intercepters/json",function(){  
  2.     console.log("本模块处理前端发过来的JSON数据");  
  3.     return mass.intercepter(function(req, res, err){  
  4.         reqreq.body = req.body || {};  
  5.         if (req._body  || 'GET' == req.method || !~req.mime.indexOf("json")){  
  6.             console.log("进入json回调")  
  7.             return true;  
  8.         }else{  
  9.             var buf = '';  
  10.             req.setEncoding('utf8');  
  11.             function buildBuffer(chunk){  
  12.                 buf += chunk;  
  13.             }  
  14.             req.on('data', buildBuffer);  
  15.             req.once('end', function(){  
  16.                 try {  
  17.                     req.body = JSON.parse(buf);  
  18.                     req._body = true;  
  19.                     req.emit("next_intercepter",req,res);  
  20.                 } catch (err){  
  21.                     err.status = 400;  
  22.                     req.emit("next_intercepter",req,res,err);  
  23.                 }finally{  
  24.                     req.removeListener("data",buildBuffer);  
  25.                 }  
  26.             });  
  27.         }  
  28.     })  
  29. }) 

而在这么多拦截器中,最重要的是matcher拦截器,它进入框架MVC系统的入口。把原始请求的pathname取出来,然后通过正则匹配它,只要一个符合就停下来,然后加载对应的控制器文件,调用相应的action处理请求!

  1. mass.define("intercepters/matcher","url",function(URL){  
  2.     console.log("用于匹配请求过来的回调")  
  3.     return mass.intercepter(function(req,res){  
  4.         console.log("进入matcher回调");  
  5.         var pathname = URL.parse(req.url).pathname, is404 = true,method = req.method, arr = mapper[method];  
  6.         for(var i =0, obj; obj = arr[i++];){  
  7.             if(obj.matcher.test(pathname)){  
  8.                 is404 = false 
  9.                 var url = mass.adjustPath("app/controllers/",obj.namespace, obj.controller+"_controller.js")  
  10.                 mass.require(obj.controller+"_controller("+url +")",function(object){  
  11.                     object[obj.action](req,res);//进入控制器的action!!!  
  12.                     console.log(obj.action)  
  13.                 },function(){  
  14.                     var err = new Error;  
  15.                     err.statusCode = 404 
  16.                     req.emit("next_intercepter",req,res,err);  
  17.                 })  
  18.                 break;  
  19.             }  
  20.         }  
  21.         if(is404){  
  22.             var err = new Error;  
  23.             err.statusCode = 404 
  24.             req.emit("next_intercepter",req,res,err);  
  25.         }  
  26.     })  
  27. }) 

最后殿后的是handle404拦截器:

  1. mass.define("intercepters/handle404","fs,path",function(fs){  
  2.     console.log("本模块用于处理404错误");  
  3.     return function(req, res, err){  
  4.         console.log("进入handle404回调");  
  5.         var accept = req.headers.accept || '';  
  6.         if (~accept.indexOf('html')) {  
  7.             res.writeHead(404, {  
  8.                 "Content-Type": "text/html"  
  9.             });  
  10.             var html = fs.readFileSync(mass.adjustPath("public/404.html"))  
  11.             res.write((html+"").replace("{{url}}",req.url));  
  12.             res.end();  
  13.         } else if (~accept.indexOf('json')) {//json  
  14.             var error = {  
  15.                 message: err.message,   
  16.                 stack: err.stack  
  17.             };  
  18.             for (var prop in err) error[prop] = err[prop];  
  19.             var json = JSON.stringify({  
  20.                 error: error  
  21.             });  
  22.             res.setHeader('Content-Type', 'application/json');  
  23.             res.end(json);  
  24.         // plain text  
  25.         } else {  
  26.             res.writeHead(res.statusCode, {  
  27.                 'Content-Type': 'text/plain'  
  28.             });  
  29.             res.end(err.stack);  
  30.         }  
  31.     }  
  32. }) 

再回过头来看控制器部分,从模板中生成的controller非常简单:

  1. mass.define("comments_controller",function(){  
  2.     return {  
  3.         "index":function(){},  
  4.         "create":function(){},  
  5.         "new":function(){},  
  6.         "edit":function(){},  
  7.         "destroy":function(){},  
  8.         "update":function(){},  
  9.         "show":function(){}  
  10.     }  
  11.  }); 

因此你需要动手改到其可用,如

  1. "show":function(req,res){  
  2.     
  3.     res.writeHead(200, {  
  4.         "Content-Type": "text/html"  
  5.     });  
  6.     var html = fs.readFileSync(mass.adjustPath("app/views/tests/show.html"))  
  7.     res.write(html);  
  8.     res.end();  
  9.                

以后会判定action的结果自动调用视图。

当然现在框架还很简单,只用了半天时间而已。它必须支持ORM与静态文件缓存才行。此外还有cookie,session等支持,这些做成一个拦截器就行了。

总结如下:

◆ 判定网站是否存在,没有通过手脚架构建一个

◆ 读取routes等配置文件,生成MVC系统所需要的控制器,视图与模型。

◆ 通过热部署功能,监视用户对配置文件的修改,进一步智能生成需要控制器,视图与模型。

◆ 通过一系列拦截器处理请来,直到matcher拦截器里面进入MVC系统,这时通过模型操作数据库,渲染页面。拦截器群集的应用大大提高应用的伸缩性。现在还没有来得及得node.js的多线程,可能这里面能发掘出许多好东西呢。

原文:http://www.cnblogs.com/rubylouvre/archive/2011/12/13/2286280.html

精彩图集

赞助商链接