Go语言Revel框架详细教程
Revel是一个全栈Web框架,提供了一套完整的解决方案来构建Go语言Web应用程序。它采用了MVC(模型-视图-控制器)架构模式,包含路由、参数解析、验证、会话管理、缓存等众多功能。
目录
- 安装与设置
- 项目结构
- 控制器与路由
- 视图与模板
- 模型与数据库
- 表单处理与验证
- 会话与Cookie
- 中间件
- 测试
- 部署
- 高级特性
- 最佳实践
1. 安装与设置
安装Revel框架和命令行工具
# 安装Revel框架和命令行工具
go get github.com/revel/revel
go get github.com/revel/cmd/revel
# 验证安装
revel version
创建新项目
revel new myapp
cd myapp
运行项目
revel run myapp
默认情况下,应用会在http://localhost:9000
运行。
2. 项目结构
典型的Revel项目结构:
myapp/
app/ # 应用代码
controllers/ # 控制器
models/ # 数据模型
views/ # 视图模板
conf/ # 配置文件
app.conf # 主配置文件
routes # 路由定义
messages/ # 国际化消息
public/ # 静态资源
css/
js/
images/
tests/ # 测试代码
3. 控制器与路由
创建控制器
在app/controllers
目录下创建hello.go
:
package controllers
import "github.com/revel/revel"
type App struct {
*revel.Controller
}
func (c App) Index() revel.Result {
return c.Render()
}
func (c App) Hello(name string) revel.Result {
return c.Render(name)
}
定义路由
编辑conf/routes
文件:
# 路由规则
# 格式: METHOD PATH -> CONTROLLER.ACTION
GET / App.Index
GET /hello/{name} App.Hello
路由参数
func (c App) Show(id int) revel.Result {
return c.RenderText(fmt.Sprintf("Showing item %d", id))
}
路由配置:
GET /items/{id} App.Show
4. 视图与模板
创建视图
在app/views/App
目录下创建Hello.html
:
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello, {{.name}}!</h1>
</body>
</html>
运行 HTML
模板语法
Revel使用Go的html/template
包,支持以下功能:
<!-- 变量 -->
<p>{{.user.Name}}</p>
<!-- 条件判断 -->
{{if .isAdmin}}
<button>Delete</button>
{{end}}
<!-- 循环 -->
{{range .items}}
<li>{{.Name}}</li>
{{end}}
<!-- 包含子模板 -->
{{template "header.html" .}}
<!-- 布局 -->
{{extends "layouts/main.html"}}
{{block "content"}}
<h1>Page Content</h1>
{{end}}
运行 HTML
5. 模型与数据库
定义模型
在app/models
目录下创建user.go
:
package models
type User struct {
ID int
Name string
Email string
Password string
}
使用GORM集成数据库
- 安装GORM:
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
- 创建数据库服务:
package services
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
func InitDB() {
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
var err error
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
}
- 在控制器中使用:
func (c App) Users() revel.Result {
var users []models.User
services.DB.Find(&users)
return c.Render(users)
}
6. 表单处理与验证
表单处理
type UserForm struct {
Name string `form:"name"`
Email string `form:"email"`
Password string `form:"password"`
}
func (c App) CreateUser() revel.Result {
var form UserForm
c.Params.Bind(&form, "user")
user := models.User{
Name: form.Name,
Email: form.Email,
Password: form.Password,
}
services.DB.Create(&user)
return c.Redirect(App.Users)
}
验证
Revel提供了强大的验证功能:
type UserForm struct {
Name string `form:"name" validation:"required"`
Email string `form:"email" validation:"required,email"`
Password string `form:"password" validation:"required,min=8"`
}
func (c App) CreateUser() revel.Result {
var form UserForm
c.Params.Bind(&form, "user")
// 手动触发验证
c.Validation.Required(form.Name).Message("Name is required")
c.Validation.Email(form.Email).Message("Invalid email")
if c.Validation.HasErrors() {
c.Validation.Keep()
c.FlashParams()
return c.Redirect(App.NewUser)
}
// 处理表单...
}
7. 会话与Cookie
会话使用
// 设置会话
c.Session["username"] = "john"
// 获取会话
username := c.Session["username"]
// 删除会话
delete(c.Session, "username")
Cookie操作
// 设置Cookie
c.SetCookie(&http.Cookie{
Name: "theme",
Value: "dark",
Path: "/",
})
// 获取Cookie
theme, err := c.Request.Cookie("theme")
8. 中间件
Revel支持过滤器链作为中间件:
内置过滤器
// 在init函数中注册
func init() {
revel.Filters = []revel.Filter{
revel.PanicFilter, // 捕获panic
revel.RouterFilter, // 路由请求
revel.FilterConfiguringFilter, // 添加/移除过滤器
revel.ParamsFilter, // 解析参数
revel.SessionFilter, // 管理会话
revel.FlashFilter, // 管理闪存消息
revel.ValidationFilter, // 处理验证
revel.I18nFilter, // 国际化
revel.InterceptorFilter, // 拦截器
revel.ActionInvoker, // 调用控制器方法
}
}
自定义过滤器
func AuthFilter(c *revel.Controller, fc []revel.Filter) {
if c.Session["user"] == nil && c.Action != "App.Login" {
c.Redirect(App.Login)
return
}
fc[0](c, fc[1:])
}
// 注册过滤器
func init() {
revel.Filters = []revel.Filter{
AuthFilter,
revel.PanicFilter,
// ...其他过滤器
}
}
9. 测试
Revel提供了测试支持:
控制器测试
package tests
import (
"net/http"
"testing"
"github.com/revel/revel"
"github.com/revel/revel/testing"
)
type AppTest struct {
testing.TestSuite
}
func (t *AppTest) TestIndex() {
t.Get("/")
t.AssertOk()
t.AssertContentType("text/html")
}
func (t *AppTest) TestHello() {
t.Get("/hello/John")
t.AssertOk()
t.AssertContains("Hello, John")
}
func TestMain(m *testing.M) {
revel.Init("dev", "myapp", "")
m.Run()
}
运行测试:
go test ./...
10. 部署
生产配置
修改conf/app.conf
:
app.name = myapp
http.port = 9000
mode = prod
results.pretty = false
watch = false
构建和运行
# 构建应用
revel package myapp
# 运行
./myapp/run.sh
使用Nginx反向代理
Nginx配置示例:
nginx
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
11. 高级特性
作业调度
import "github.com/revel/modules/jobs/app/jobs"
func init() {
revel.OnAppStart(func() {
jobs.Schedule("@every 1h", jobs.FuncJob(func() {
// 每小时执行的任务
}))
})
}
缓存
// 设置缓存
revel.Cache.Set("key", "value", 30*time.Minute)
// 获取缓存
value, found := revel.Cache.Get("key")
国际化
- 创建消息文件
messages/en
:
greeting=Hello
- 在控制器中使用:
func (c App) Index() revel.Result {
greeting := c.Message("greeting")
return c.Render(greeting)
}
12. 最佳实践
项目组织:
- 保持控制器简洁,将业务逻辑移到服务层
- 使用模块化设计,将相关功能分组
- 错误处理:
func (c App) Action() revel.Result {
if err := doSomething(); err != nil {
c.Log.Errorf("Error: %v", err)
c.Response.Status = http.StatusInternalServerError
return c.RenderError(errors.New("Something went wrong"))
}
return c.Render()
}
安全实践:
- 使用HTTPS
- 防止CSRF(Revel内置支持)
- 验证和清理所有用户输入
性能优化:
- 启用模板缓存:
template.cache = true
- 使用数据库连接池
- 减少全局变量使用
- 启用模板缓存:
- 日志记录:
// 在控制器中
c.Log.Info("Processing request")
c.Log.Errorf("Error: %v", err)
// 全局日志
revel.AppLog.Info("Application started")
Revel是一个功能全面的框架,适合构建中大型Web应用程序。通过本教程,你应该已经掌握了Revel的核心概念,可以开始构建自己的应用了。