上篇文档我们是通过在server.js中对不同的url_path来执行不同的请求逻辑(行为驱动执行)。其实,这是最直接最原始的实现方式,往往我们会把一大坨的逻辑处理放到一起来搞,就像以前学习VB6的时候,一个vb文件可能包含了用户登录、用户信息CRUD等等,甚至上千行代码。代码的冗余度很大,没有模块化。
Node.js具是有模块和包的设计概念,比如server.js就是最普通的一个独立模块,还有require("http")中的http模块就是引入的c/c++扩展类库。下面将路由的概念和设计引入,咱们要避免重复的if/else分支,多用一些脚本语言的特性,尽量简化server.js中的if/else逻辑。怎么做呢?
类比Java Web开发中常用的Struts框架,就是解决了servlet开发中的if/else问题,通过核心Action类和配置文件来管理请求入口。我们可以如下方法,来简单处理,将每个请求分支配置起来(放到一个handle对象中,通过这个对象来对映射不同的action)。
先新建一个requestHandlers.js(action模块):
function start(response){
response.writeHead(200,{"Content-Type":"text/plain"});
response.write("start") ;
response.end();
return ("Request handler 'start' was called.");
}
function upload(response){
response.writeHead(200,{"Content-Type":"text/plain"});
response.write("upload") ;
response.end();
return ("Request handler 'upload' was called.");
}
exports.start = start;
exports.upload = upload;
修改 route.js(路由模块)为:
//把response对象传给handlers模块,直接将结果返回到页面或进行处理。
function route(handle,pathname,response){
console.log(typeof handle[pathname]) ;
//判断当前映射的action是否为一个函数
if(typeof handle[pathname] === 'function') {
//不用知道这里的handle是什么对象,直接执行handle的特定方法就可以
var content = handle[pathname](response);
console.log("handle content: "+content) ;
}else{
console.log("No request handler found for " + pathname) ;
response.write(404,{"Content-Type":"text/plain"});
response.write("404 not found");
response.end();
}
}
修改server.js为:
var http = require("http");
var url = require("url");
function start(route,handle) {
function onRequest(request,response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for "+pathname+" received.") ;
//调用路由模块
route(handle,pathname,response);
}
http.createServer(onRequest).listen(3333);
console.log("Server has started");
}
exports.start = start;
修改index.js(页面入口)为:
var server = require("./service/server") ;
var router = require("./service/route");
var requestHandlers = require("./service/requestHandlers");
//创建handle映射类,就是将请求路径和具体的action函数进行映射关联
//var handle = {"/":requestHandlers.start,
// "/start":requestHandlers.start,
// "/upload":requestHandlers.upload};
var handle = {};
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
console.dir(["handle",handle]);
server.start(router.route,handle);