通过前面几章,我们已经掌握了一些基本的开发知识,但是代码结构比较简单,缺乏统一的标准,模块化,也缺乏统一的异常处理,这一章我们主要来学习如何封装一个轻量级的MVC框架,规范以及简化开发,并且提供类似php所见即所得的能力

统一入口

通常来说一个mvc框架会有一个统一的入口点,类似于spring mvc的DispatcherServlet,会拦截所有的请求,也就是/,于是我们可以得出我们的入口点

conf/nginx.conf

worker_processes  1;

error_log logs/error.log notice;

events {
worker_connections 1024;
} http {
lua_package_path "/Users/john/opensource/openresty-web-dev/demo8/lua/?.lua;/Users/john/opensource/openresty-web-dev/demo8/lualib/?.lua;/usr/local/openresty/lualib/?.lua";
server {
listen 80;
server_name localhost;
lua_code_cache off; location / {
content_by_lua_file lua/mvc.lua;
} location ~ ^/js/|^/css/|\.html {
root html;
}
}
}

除了静态文件js/css/html文件,其他的请求都会被我们的mvc.lua处理。

默认页面

当请求uri为空时,默认返回index.html页面,当然也可以自己定义,实现这个效果很简单

local uri = ngx.var.uri
-- 默认首页
if uri == "" or uri == "/" then
local res = ngx.location.capture("/index.html", {})
ngx.say(res.body)
return
end

url解析

这里简单的把url解析成模块名模块方法,根据/分割,如果只有模块名,没有方法名,则默认为index方法

local m, err = ngx.re.match(uri, "([a-zA-Z0-9-]+)/*([a-zA-Z0-9-]+)*")

local moduleName = m[1]     -- 模块名
local method = m[2] -- 方法名 if not method then
method = "index" -- 默认访问index方法
else
method = ngx.re.gsub(method, "-", "_")
end

动态Controller模块

得到模块名之后,需要动态引入模块,通过pcall,然后再调用模块的方法

-- 控制器默认在web包下面
local prefix = "web."
local path = prefix .. moduleName -- 尝试引入模块,不存在则报错
local ret, ctrl, err = pcall(require, path) local is_debug = true -- 调试阶段,会输出错误信息到页面上 if ret == false then
if is_debug then
ngx.status = 404
ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. ctrl .. "</span> module not found !</p>")
end
ngx.exit(404)
end -- 尝试获取模块方法,不存在则报错
local req_method = ctrl[method] if req_method == nil then
if is_debug then
ngx.status = 404
ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. method .. "()</span> method not found in <span style='color:red'>" .. moduleName .. "</span> lua module !</p>")
end
ngx.exit(404)
end -- 执行模块方法,报错则显示错误信息,所见即所得,可以追踪lua报错行数
ret, err = pcall(req_method) if ret == false then
if is_debug then
ngx.status = 404
ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. err .. "</span></p>")
else
ngx.exit(500)
end
end

异常处理

可以看到,从引入模块,到获取模块方法,已经执行方法,都有可能报错,这里通过pcall来进行调用,这种方式可以安全的调用lua代码,不会导致异常中断,然后通过定义一个变量,来区分是否为开发调试阶段,如果是则把错误信息输出到浏览器端,否则直接报404或者500,避免把错误信息输出到客户端,导致代码泄漏。

至此,一个简单的mvc框架已经可以使用了,但是现在还只能做前端渲染,下一章,我讲介绍如果进行服务端渲染。

示例代码 参见demo8部分

openresty 前端开发轻量级MVC框架封装一(控制器篇)的更多相关文章

  1. openresty 前端开发轻量级MVC框架封装二(渲染篇)

    这一章主要介绍怎么使用模板,进行后端渲染,主要用到了lua-resty-template这个库,直接下载下来,放到lualib里面就行了,推荐第三方库,已经框架都放到lualib目录里面,lua目录放 ...

  2. openresty 前端开发入门五之Mysql篇

    openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ...

  3. .NET轻量级MVC框架:Nancy入门教程(二)——Nancy和MVC的简单对比

    在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world.看到大家的评论,都在问Nancy的优势在哪里?和微软的MVC比 ...

  4. 准备.Net转前端开发-WPF界面框架那些事,值得珍藏的8个问题

    题外话 不出意外,本片内容应该是最后一篇关于.Net技术的博客,做.Net的伙伴们忽喷忽喷..Net挺好的,微软最近在跨平台方面搞的水深火热,更新也比较频繁,而且博客园的很多大牛也写的有跨平台相关技术 ...

  5. PHP做Web开发的MVC框架(Smarty使用说明 )

    PHP做Web开发的MVC框架(Smarty使用说明 ) 一.Smarty简明教程 1.安装演示 下载最新版本的Smarty-3.1.12,然后解压下载的文件.接下来演示Smarty自带的demo例子 ...

  6. 上门洗车APP --- Androidclient开发 之 网络框架封装介绍(二)

    上门洗车APP --- Androidclient开发 之 网络框架封装介绍(二) 前几篇博文中给大家介绍了一下APP中的基本业务及开发本项目使用的网络架构: 上门洗车APP --- Androidc ...

  7. Java Servlet开发的轻量级MVC框架最佳实践

    在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发. 关于Servlet开发的基础知识,请看 ...

  8. openresty 前端开发序

    还记得第一次尝试前后端分离的时候,是使用nginx + react 构建的spa应用,后端是java,主要处理业务逻辑逻辑部分,返回json数据,在nginx里面配置好html + js纯静态文件,再 ...

  9. .NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy

    当我们要接到一个新的项目的时候,我们第一时间想到的是用微软的MVC框架,但是你是否想过微软的MVC是不是有点笨重?我们这个项目用MVC是不是有点大材小用?有没有可以替代MVC的东西呢?看到这里也许你会 ...

随机推荐

  1. 安装WindowsXP操作系统(安装版) - 初学者系列 - 学习者系列文章

    本文主要介绍下Windows XP操作系统的安装. 1.             将光驱装入光驱.启动电脑,在开始界面按下DEL键,进入BIOS设置界面.将光驱设置为第一启动项.下面以虚拟机为例子. ...

  2. Machine Learning - XI. Machine Learning System Design机器学习系统的设计(Week 6)

    http://blog.csdn.net/pipisorry/article/details/44119187 机器学习Machine Learning - Andrew NG courses学习笔记 ...

  3. Android 获取截图 并将其保存到本地sd在卡路径

    /** * 获取当前屏幕和保存截图 */ private void GetandSaveCurrentImage() { //1.构建Bitmap WindowManager windowManage ...

  4. Java凝视Override、Deprecated、SuppressWarnings详细解释

    一.什么是视线     说起目光,你必须先提什么是元数据(metadata). 所谓元数据是数据的数据.那.元数据是描述数据的叙述. 像在表中的数据字段,叙述了这个字段下的数据的含义.而J2SE5.0 ...

  5. mediawiki在windows下的安装

    mediawiki在windows下的安装 对于刚接触wiki的朋友们来说,配置一个服务器环境,安装并运行mediawiki是一件很麻烦的事情,在这里,我尽量用通俗易懂的语言,介绍mw(mediawi ...

  6. svn外网访登录不进去提示证书错误Authorization Required

    为了外网能访问内网svn.于是坐在外网端口映射.但是奇怪的是内网能访问,外网总也登录不进去.以为是浏览器版本低 但是其他浏览器也一样.最后客户端也登录不进去.提示报错:  Authorization  ...

  7. xquery

    XQuery 相对于 XML,等同于 SQL 相对于数据库.设计用来查询 XML 数据.- 不仅仅限于 XML 文件,还包括任何可以 XML 形态呈现的数据,包括数据库. FLWOR 是 " ...

  8. SZU:B47 Big Integer II

    Judge Info Memory Limit: 32768KB Case Time Limit: 10000MS Time Limit: 10000MS Judger: Normal Descrip ...

  9. 关于sscanf函数的各种详细用法

    看书的时候碰到sscanf函数,就上网查了很多资料,并加以自己的整理,希望对大家有所帮助. (因为参考的博客太多太散,就不一一注明,望大神们见谅) sscanf()  :从一个字符串中读进与指定格式相 ...

  10. ps -aux中的time 的意思

    ps -aux 显示所有包含其他使用者的行程 aux 输出格式 : USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND USER: 行程拥有者 ...