ホームページ  >  記事  >  バックエンド開発  >  Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

尚
転載
2019-11-26 11:29:412875ブラウズ

Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

ユーザー登録、ログイン、ログアウトはWebサイトでは避けられない機能であり、車輪の再発明が必要な領域とも言えます。 . 何度もやりました。このような小さな機能から、実際に使用されている Web フレームワークのほとんどのことがわかります。

この基本モジュールを使用して、今日のレベルを見てみましょう。

まず、選択した技術フレームワークとコンポーネントを整理しましょう:

Web フレームワーク: revel

データベース: mongodb

データベース ドライバー: 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 フレームワークです。

Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

#プロジェクト全体を実行する準備ができました。次のコマンド ラインを実行してサイトを開始します。

revel run myapp

ブラウザ http://127.0.0.1:9000 を開くと、次の結果が表示されます。

Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

詳細については説明しません。とりあえず内部の詳細を説明します。さあ、まずユーザーを登録しましょう。ほとんどの場合、開発プロセス全体で revel を再起動する必要はありません。

1. モデルの準備

MVC の開発リズムに従い、まずモデルを準備します。アプリ ディレクトリに新しいモデル ディレクトリを作成し、その中に新しいentity.goを作成し(このファイルに任意の名前を付けることができます)、entity.goを開いてユーザーのエンティティ定義を追加します。

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

内部の詳細については今回は割愛しますので、まずはユーザー登録をしてみましょう。ほとんどの場合、開発プロセス全体で revel を再起動する必要はありません。

1. モデルの準備

MVC の開発リズムに従い、まずモデルを準備します。アプリ ディレクトリに新しいモデル ディレクトリを作成し、その中に新しいentity.goを作成し(このファイルに任意の名前を付けることができます)、entity.goを開いてユーザーのエンティティ定義を追加します。

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

次に、登録に必要なメソッドを実装し、ファイル dal_account を app\models ディレクトリに追加します。 . 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. コントローラーの準備

コントローラーを準備し、app\controllers に account.go というファイルを新規作成し、その中にアカウントコントローラーを実装するコードは以下の通りです。

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. ルートの追加

ルートを準備し、conf\routes を開いて、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 の意味を知っていると仮定して、ここでは 2 つの URL をコントローラーの 2 つのアクションにマッピングしています。

ご覧のとおり、すべての URL とコントローラー間のマッピングがここで定義されており、非常に便利です。このファイルは、コンパイルに参加するために実行する前に、revel によって app\routes\routes.go ファイルに変換されます。このファイルの内容は、後で ReverseRedirect について説明するときに使用します。

4. ビューの準備

ビューを準備し、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}}
    …

上記の青い部分の説明by bit キーワードの意味。

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。

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

Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

$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看看吧。是不是这样呢?

Go 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)

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 言語はレベル フレームワークを使用してユーザー登録チュートリアルを実装します (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。