用到的知识点

mvc架构
模型渲染库:https://github.com/bungle/lua-resty-template
resty http请求库: https://github.com/bungle/lua-resty-template

参照 mvc模型来做postman工具

配置文件说明

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    lua_package_path "/open_resty/lualib/?.lua;/usr/local/openresty/lualib/?.lua;";
    server {
        listen 8080;
        default_type 'application/json;charset=utf8';
        lua_code_cache off;

        location /  {
            content_by_lua_file mvc.lua;
        }

        location ~ ^/js/|^/css/|\.html {
            root static;
        }
    }
}
  • lua_code_cache off; 是为了修改lua脚本后不用重启nginx自动加载lua。- lua_package_path: lua脚本路径- root static: 静态目录是static

入口文件/解析uri

mvc.lua

#!/usr/bin/lua

ngx.say("<br/>")

local uri = ngx.var.uri
ngx.header.content_type="application/json;charset=utf8"

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

--- uri解析
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模块
-- 控制器默认在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

控制器

控制器路径: lua/web/index.lua, lua/web/postman.lua
lua/web/index.lua 渲染模板 lua/tpl/index.html

local template = require "resty.template"
local _M = {}
function _M.index()
    local model = {reqUrl = "hello template", reqBody = "body"}
    
    -- 1、外部模板文件
     template.render("/index.html", model)
end
return _M

lua/web/postman.lua实现接收表单数据并处理Post逻辑

local template = require "resty.template"
local postman = require("cus.postman")

local _M = {}
local function Parse()
    local model = {}
    local request_method = ngx.var.request_method
    local args = nil
    local Body = nil
    local CurTime = nil
    local CheckSum = nil
    local MD5 = nil
    local host = nil
    if "GET" == request_method then
        args = ngx.req.get_uri_args()
    elseif "POST" == request_method then
        ngx.req.read_body()
        --获取post请求的参数
        local post_args_tab = ngx.req.get_post_args()
        for k, v in pairs(post_args_tab) do
            model[k]=v
        end
        Body = ngx.req.get_body_data()
    end
    model["resp"] = postman.httpPost(model["reqUrl"], model["reqBody"])
    return model
end
function _M.index()
    local model = Parse()
    -- 1、外部模板文件
     template.render("/index.html", model)

end
return _M

模板代码

lua/tpl/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PostMan</title>
</head>
<body>
<div style="text-align: center; float: left">
    <div><h1>PostMain</h1></div>
    <div>
        <form action="/postman/index" method="post" name="postman">
            <table style="width: 500px;height: 200px">
                <tr>
                    <td>请求地址:</td>
                    <td><input id="reqUrl" name="reqUrl" type="text" style="width: 300px;height: 35px;"  value="{*reqUrl*}"/></td>
                </tr>
                <tr>
                    <td>请求body:</td>
                    <td><textarea id="reqBody" name="reqBody" type="text"  style="width: 300px;height: 55px">{*reqBody*}</textarea></td>
                </tr>
                <tr>
                    <td>返回值:</td>
                    <td><textarea id="resp" name="resp" disabled style="width: 300px;height: 105px">{*resp*}</textarea></td>
                </tr>
            </table>
            <input id="btn" type="submit" value="提交"/>
        </form>

    </div>

</div>

</body>

</html>

使用方法

访问地址: http://ip:8080/index/index
第一个index代表lua/web/index.lua
第二个index代表lua/web/index.lua文件中的index方法。

lua_resty_template模板渲染方法

  1. 使用template.render
local template = require "resty.template"
template.render("/index.html", model)

2.使用template.new

local template = require "resty.template" -- Using template.new

 local view = template.new  "view.html" view.message = "Hello, World!" view:render()
  1. 使用template.compile
local template = require "resty.template" 
local func = template.compile("view.html") 
--执行函数,得到渲染之后的内容 
local content = func(context) ngx.say(content)

模板语法

  • {<!-- -->{expression}}:输出传递的值,转义html相关标签- {*expression*}:输出传递的值- {% lua code %}:使用lua代码- {(template)}:引入html共用页面- {(base.html, { title = "Hello, World" } )}:引入html共用页面,并传递相关值- {-verbatim-}...{-verbatim-}/{-raw-}...{-raw-}:可原样输出模板语法- {# comments #}:在模板中使用注释,不会被执行和输出

遇到的坑

网页上直接输出了html字符串。而不是正常网页
解决办法
nginx.conf配置文件加上default_type text/html;

server {
    default_type text/html;
    location / {
            default_type text/html;
    }
}

入口文件mvc.lua开头加上下面的内容:

ngx.say("<br/>")

项目地址

https://github.com/diycat1024/OpenRestyPostman

--完--