搜索
首页后端开发Golanggo语言使用revel框架实现用户注册教程(附代码)

go语言使用revel框架实现用户注册教程(附代码)

用户注册、登录和注销是任何一个网站都必然会有的功能,可以说,这是重新造轮子做多的领域,每个做网站的人应该都做过很多遍。见微知著,从这么一个小功能其实就可以看到所使用的web框架中的大部分东西。

今天就让我们用这个基本模块来看看revel吧。

先整理一下我们选用的技术框架和组件:

web框架:revel 

数据库:mongodb

数据库driver:mgo

工欲善其事,必先利其器,这里着重推荐一个mongodb的GUI客户端 - mongovue,可以说,如果没有这个工具,在开发的过程中我们会痛苦许多许多。

这里假设你已经有了对Go语言最基本的知识,已经配置好GOROOT和GOPATH。

首先,在GOPATH下面运行下面的命令安装revel,并且把revel的工具编译出来。

go get github.com/robfig/revel
go build –o bin/revel.exe github.com/robfig/revel/revel

完成之后去GOPATH\bin下面看看是否已经编译出来了revel.exe。为了方便使用,我把GOPATH\bin添加到了环境变量PATH中。

到你希望存放工程文件的地方运行

revel new myapp

整个工程的框架就建立好了,看下面的文件夹结构就可以看出,revel是一个MVC框架。

1.jpg

此时整个工程就可以运行了,运行下面的命令行启动站点。

revel run myapp

打开浏览器 http://127.0.0.1:9000,就可以看到下面的结果

2.jpg

内部的细节暂时不多说,来吧,先让用户可以注册。注意,在整个开发过程中大部分时候不需要重新启动revel。

1、准备Model

按照MVC的开发节奏,我们先准备model。在app目录下新建一个models目录,然后在里面新建entity.go(这个文件的命名大家可自便),打开entity.go加入User的实体定义。

type User struct {
  Email    string
  Nickname string
  Password []byte
}
type MockUser struct {
  Email           string
  Nickname        string
  Password        string
  ConfirmPassword string
}

内部的细节暂时不多说,来吧,先让用户可以注册。注意,在整个开发过程中大部分时候不需要重新启动revel。

1、准备Model

按照MVC的开发节奏,我们先准备model。在app目录下新建一个models目录,然后在里面新建entity.go(这个文件的命名大家可自便),打开entity.go加入User的实体定义。

type User struct {
  Email    string
  Nickname string
  Password []byte
}
type MockUser struct {
  Email           string
  Nickname        string
  Password        string
  ConfirmPassword string
}

为什么定义MockUser呢?原因后面会提到。

现在写dal(数据访问层),在app\models目录下新建dal.go。dal的写法其实可以用revel的插件机制,这里为了避免一下子引入太多概念,先用这种简单的方式。

package models
import (
  "github.com/robfig/revel"
  "labix.org/v2/mgo"
)
const (
  DbName                         = "myapp"
  UserCollection                 = "user"
)
type Dal struct {
  session *mgo.Session
}
func NewDal() (*Dal, error) {
  revel.Config.SetSection("db")
  ip, found := revel.Config.String("ip")
  if !found {
    revel.ERROR.Fatal("Cannot load database ip from app.conf")
  }
  session, err := mgo.Dial(ip)
  if err != nil {
    return nil, err
  }
  return &Dal{session}, nil
}
func (d *Dal) Close() {
  d.session.Close()
}

revel已经提供了配置系统,打开conf\app.conf,添加下面内容

[db]
ip = 127.0.0.1

现在实现注册需要用到的方法,在app\models目录下添加文件dal_account.go,代码如下。

func (d *Dal) RegisterUser(mu *MockUser) error {
  uc := d.session.DB(DbName).C(UserCollection)
  //先检查email和nickname是否已经被使用
  i, _ := uc.Find(M{"nickname": mu.Nickname}).Count()
  if i != 0 {
    return errors.New("用户昵称已经被使用")
  }
  i, _ = uc.Find(M{"email": mu.Email}).Count()
  if i != 0 {
    return errors.New("邮件地址已经被使用")
  }
  var u User
  u.Email = mu.Email
  u.Nickname = mu.Nickname
  u.Password, _ = bcrypt.GenerateFromPassword([]byte(mu.Password), bcrypt.DefaultCost)
  err := uc.Insert(u)
  return err
}

看出来MockUser存在的意义了吗?用户在页面上填写的是明文的密码,这可不能直接存入数据库,需要先加密,这里用到了"code.google.com/p/go.crypto/bcrypt"这个库。

2、准备Controller

准备controller,在app\controllers新建一个文件account.go,在里面实现Account控制器,代码如下。

package controllers
import (
  "github.com/robfig/revel"
  "myapp/app/models"
)
type Account struct {
  *revel.Controller
}
func (c *Account) Register() revel.Result {
  return c.Render()
}
func (c *Account) PostRegister(user *models.MockUser) revel.Result {
  return c.Render()
}

3、添加Route

准备route,打开conf\routes,添加Register的URL映射。

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
module:testrunner
GET     /                                          App.Index
GET     /register                                Account.Register
POST   /register                                Account.PostRegister
# Ignore favicon requests
GET     /favicon.ico                           404
# Map static resources from the /app/public folder to the /public path
GET     /public/*filepath                     Static.Serve("public")
# Catch all
*       /:controller/:action                   :controller.:action

假定大家都知道Restful是啥意思,这里就是把两个url映射到了Controller的两个Action。

可以看到,这里定义了所有的URL到Controller之间的映射,很方便。这个文件在运行前会被revel转换成app\routes\routes.go文件参与编译。后面在讲到ReverseRedirect的时候需要用到这个文件里的内容。

4、准备View

准备view,在app\views下面新建文件Register.html,关键内容如下

<form action="{{url "Account.PostRegister"}}" method="POST">
    {{with $field := field "user.Email" .}}
    <div class="control-group {{$field.ErrorClass}}">
      <label class="control-label" for="{{$field.Id}}">电子邮件</label>
      <div class="controls">
        <input type="email" id="{{$field.Id}}" name="{{$field.Name}}" value="{{$field.Flash}}" required>
        {{if $field.Error}}
        <span class="help-inline">{{$field.Error}}</span>
        {{end}}
      </div>
    </div>
    {{end}}
    …

一点一点解释一下上面蓝色部分关键字的含义。

url是revel提供的一个template function,可以很方便的把Controller的Action变成与之相对的url,它的运作原理实际上就是去刚才定义好的routes映射里面查找。

field是revel提供的一个template function,专门方便生成form,还记得PostRegister方法的签名吗?

func (c *Account) PostRegister(user *models.MockUser) revel.Result

它接受一个名为user的*models.User类型的参数,所以,使用{{with $field := field “user.Email”}}就可以通知revel将form的参数封装到user结构中再传递给PostRegister。

我们都知道用户注册的时候填写的值是需要做有效性检验的,当用户填写的值不符合标准时需要出现错误提示,通常来说会是下面这样

3.jpg

$field.ErrorClass的作用就是当这个参数出现错误的时候可以方便的通过添加class的方式在页面上显示错误状态。ErrorClass的值可以通过下面的代码修改。

revel.ERROR_CLASS = "error"

$field.Id和$field.Name就不解释了,大家待会儿打开浏览器中看看生成的源代码就明白了。

$field.Flash这里就需要解释一下Flash的概念了。

Flash是一个字典,适用于在两个Request中间传递数据,数据存储在cookie中。

大家都知道,HTTP协议本身是无状态的,所以,考虑一下这个用例,用户在注册的时候输入了一个无效的email地址,点击注册之后页面刷新了一下,“电子邮件”下面出现一行红字“你输入的Email地址无效”,此刻文本框里面需要出现上次用户输入的值。那么,$field.Flash就是在Flash里去找以$field.Name为Key的值。

$field.Error就是在Flash里找以$field.Name_error为Key的值,也就是上图中红色的“密码必须大于等于6位”这个错误信息。

好了,现在大家就按照这个节奏在view中添加“昵称”,“密码”和“确认密码”吧。

添加完成之后就去访问http://127.0.0.1/register看看吧。是不是这样呢?

4.jpg

revel会通过Controller.Action的名称去查找同名的view文件,例如,Register方法对应的就是Register.html。这里需要注意的一点是,revel是通过反射去查找Controller.Render方法的调用者,而且只向上查找一层。

例如,下面这段代码是不能工作的。

func (c *Account) someMethod() revel.Result {
  ...
  return c.Render()
}
func (c *Account) Register() revel.Result {
  return c.someMethod()
}

5. 实现Controller

现在让我们为PostRegister添加处理注册的逻辑。

首先,验证参数的有效性。

func (c *Account) PostRegister(user *models.MockUser) revel.Result {
  c.Validation.Required(user)
  c.Validation.Email(user.Email)
  c.Validation.Required(user.Nickname)
  c.Validation.Required(user.Password)
  c.Validation.Required(user.ConfirmPassword == user.Password)
  if c.Validation.HasErrors() {
    c.FlashParams()
    return c.Redirect((*Account).Register)
  }
  return c.Render()
}

revel提供了挺好用的Validation机制,上面的代码应该不需要太多解释,只有一行

c.FlashParams()

它的作用就是把form提交的参数原样存入Flash中,还记得刚才的$field.Flash吗?

现在去玩玩注册页面吧,填写一些错误的值看看反应吧,嗯,你应该很快就会发现,错误信息虽然已经显示出来,但可惜却是英文的,修改一下吧。

func (c *Account) PostRegister(user *models.MockUser) revel.Result {
  c.Validation.Email(user.Email).Message("电子邮件格式无效")
  c.Validation.Required(user.Nickname).Message("用户昵称不能为空")
  c.Validation.Required(user.Password).Message("密码不能为空")
  c.Validation.Required(user.ConfirmPassword == user.Password).Message("两次输入的密码不一致")
  if c.Validation.HasErrors() {
    c.FlashParams()
    return c.Redirect((*Account).Register)
  }
  return c.Render()
}

Validation提供了好几个常用的验证方法,大家可以自己看看,应该是简单易懂的。

继续,当所有参数检查都通过之后,就调用dal.RegisterUser方法将用户信息存入数据库。

func (c *Account) PostRegister(user *models.MockUser) revel.Result {
  c.Validation.Email(user.Email).Message("电子邮件格式无效")
  c.Validation.Required(user.Nickname).Message("用户昵称不能为空")
  c.Validation.Required(user.Password).Message("密码不能为空")
  c.Validation.Required(user.ConfirmPassword == user.Password).Message("两次输入的密码不一致")
  if c.Validation.HasErrors() {
    c.FlashParams()
    return c.Redirect((*Account).Register)
  }
  dal, err := models.NewDal()
  if err != nil {
    c.Response.Status = 500
    return c.RenderError(err)
  }
  defer dal.Close()
  err = dal.RegisterUser(user)
  if err != nil {
    c.Flash.Error(err.Error())
    return c.Redirect((*Account).Register)
  }
  return c.Redirect((*Account).RegisterSuccessful)
}
func (c *Account) RegisterSuccessful() revel.Result {
  return c.Render()
}

我增加了一个方法RegisterSuccessful,用于显示注册成功,大家别忘了在routes和view中添加相应的东西。

至此,用户注册已经完成。不知道大家注意到没有,就算修改go代码,依然不需要重新启动revel,直接刷新浏览器页面就会发现新的代码已经自动编译并且启用了。

更多go语言相关文章请关注go语言教程栏目。

以上是go语言使用revel框架实现用户注册教程(附代码)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:博客园。如有侵权,请联系admin@php.cn删除
Golang行动:现实世界中的示例和应用程序Golang行动:现实世界中的示例和应用程序Apr 12, 2025 am 12:11 AM

Golang在实际应用中表现出色,以简洁、高效和并发性着称。 1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Golang:Go编程语言解释了Golang:Go编程语言解释了Apr 10, 2025 am 11:18 AM

Go语言的核心特性包括垃圾回收、静态链接和并发支持。1.Go语言的并发模型通过goroutine和channel实现高效并发编程。2.接口和多态性通过实现接口方法,使得不同类型可以统一处理。3.基本用法展示了函数定义和调用的高效性。4.高级用法中,切片提供了动态调整大小的强大功能。5.常见错误如竞态条件可以通过gotest-race检测并解决。6.性能优化通过sync.Pool重用对象,减少垃圾回收压力。

Golang的目的:建立高效且可扩展的系统Golang的目的:建立高效且可扩展的系统Apr 09, 2025 pm 05:17 PM

Go语言在构建高效且可扩展的系统中表现出色,其优势包括:1.高性能:编译成机器码,运行速度快;2.并发编程:通过goroutines和channels简化多任务处理;3.简洁性:语法简洁,降低学习和维护成本;4.跨平台:支持跨平台编译,方便部署。

SQL排序中ORDER BY语句结果为何有时看似随机?SQL排序中ORDER BY语句结果为何有时看似随机?Apr 02, 2025 pm 05:24 PM

关于SQL查询结果排序的疑惑学习SQL的过程中,常常会遇到一些令人困惑的问题。最近,笔者在阅读《MICK-SQL基础�...

技术栈收敛是否仅仅是技术栈选型的过程?技术栈收敛是否仅仅是技术栈选型的过程?Apr 02, 2025 pm 05:21 PM

技术栈收敛与技术选型的关系在软件开发中,技术栈的选择和管理是一个非常关键的问题。最近,有读者提出了...

如何在Go语言中使用反射对比并处理三个结构体的差异?如何在Go语言中使用反射对比并处理三个结构体的差异?Apr 02, 2025 pm 05:15 PM

Go语言中如何对比并处理三个结构体在Go语言编程中,有时需要对比两个结构体的差异,并将这些差异应用到第�...

在Go语言中如何查看全局安装的包?在Go语言中如何查看全局安装的包?Apr 02, 2025 pm 05:12 PM

在Go语言中如何查看全局安装的包?在使用Go语言开发过程中,经常会使用go...

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器