L'enregistrement des utilisateurs, la connexion et la déconnexion sont des fonctions inévitables de tout site Web. On peut dire que c'est un domaine qui réinvente la roue et que tous ceux qui créent un site Web devraient le faire. cela plusieurs fois. À partir d’une si petite fonction, vous pouvez réellement voir la plupart des éléments du framework Web utilisé.
Utilisons ce module de base pour jeter un œil à Revel aujourd'hui.
Tout d'abord, trions le framework technique et les composants que nous avons sélectionnés :
framework web : revel
base de données : mongodb
pilote de base de données : mgo
Si vous voulez bien faire votre travail, vous devez d'abord affiner vos outils. Ici, nous recommandons un client GUI mongodb - mongovue On peut dire que sans cet outil, nous aurions beaucoup de mal pendant le processus de développement. .
On suppose ici que vous possédez déjà les connaissances les plus élémentaires du langage Go et que vous avez configuré GOROOT et GOPATH.
Tout d'abord, exécutez la commande suivante sous GOPATH pour installer Revel et compiler l'outil Revel.
go get github.com/robfig/revel go build –o bin/revel.exe github.com/robfig/revel/revel
Une fois terminé, accédez à GOPATHbin pour voir si revel.exe a été compilé. Pour faciliter l'utilisation, j'ai ajouté GOPATHbin à la variable d'environnement PATH.
Allez à l'endroit où vous souhaitez stocker les fichiers du projet et exécutez
revel new myapp
L'ensemble du cadre du projet est établi Comme vous pouvez le voir dans la structure des dossiers ci-dessous, revel est un framework MVC.
L'ensemble du projet est maintenant prêt à être exécuté. Exécutez la ligne de commande suivante pour démarrer le site.
revel run myapp
Ouvrez le navigateur http://127.0.0.1:9000, vous pouvez voir les résultats suivants
Je n'entrerai pas dans les détails sur le détails internes pour l'instant. Allez, laissez les utilisateurs s'inscrire d'abord. Notez que la plupart du temps, il n’est pas nécessaire de redémarrer Revel pendant tout le processus de développement.
1. Préparer le modèle
Selon le rythme de développement de MVC, nous préparons d'abord le modèle. Créez un nouveau répertoire de modèles dans le répertoire de l'application, puis créez-y une nouvelle entité.go (vous pouvez nommer ce fichier comme vous le souhaitez), ouvrez Entity.go et ajoutez la définition de l'entité utilisateur.
type User struct { Email string Nickname string Password []byte } type MockUser struct { Email string Nickname string Password string ConfirmPassword string }
Je n'entrerai pas dans les détails internes pour l'instant, laissons d'abord les utilisateurs s'inscrire. Notez que la plupart du temps, il n’est pas nécessaire de redémarrer Revel pendant tout le processus de développement.
1. Préparer le modèle
Selon le rythme de développement de MVC, nous préparons d'abord le modèle. Créez un nouveau répertoire de modèles dans le répertoire de l'application, puis créez-y une nouvelle entité.go (vous pouvez nommer ce fichier comme vous le souhaitez), ouvrez Entity.go et ajoutez la définition de l'entité utilisateur.
type User struct { Email string Nickname string Password []byte } type MockUser struct { Email string Nickname string Password string ConfirmPassword string }
Pourquoi définir MockUser ? Les raisons seront évoquées plus tard.
Écrivez maintenant dal (couche d'accès aux données) et créez dal.go dans le répertoire appmodels. La méthode d'écriture de Dal peut en fait utiliser le mécanisme de plug-in de Revel. Afin d'éviter d'introduire trop de concepts à la fois, cette méthode simple est utilisée en premier.
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 a fourni un système de configuration, ouvrez confapp.conf, ajoutez le contenu suivant
[db] ip = 127.0.0.1
Implémentez maintenant la méthode nécessaire à l'enregistrement, ajoutez le fichier dal_account.go dans le répertoire appmodels, le le code est le suivant.
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 }
Voyez-vous le sens de l'existence de MockUser ? L'utilisateur remplit le mot de passe en texte clair sur la page, qui ne peut pas être directement stocké dans la base de données. Il doit d'abord être chiffré. La bibliothèque "code.google.com/p/go.crypto/bcrypt" est utilisée ici.
2. Préparez le contrôleur
Préparez le contrôleur, créez un nouveau fichier account.go dans appcontrollers et implémentez-y le contrôleur de compte. Le code est le suivant.
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. Ajouter un itinéraire
Préparez un itinéraire, ouvrez des routes et ajoutez un mappage d'URL d'enregistrement.
# 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
En supposant que tout le monde sache ce que Restful signifie, voici le mappage des deux URL aux deux actions du contrôleur.
Comme vous pouvez le voir, le mappage entre toutes les URL et les contrôleurs est défini ici, ce qui est très pratique. Ce fichier sera converti par revel en fichier approutesroutes.go avant d'être exécuté pour participer à la compilation. Le contenu de ce fichier sera utilisé plus tard pour parler de ReverseRedirect.
4. Préparer la vue
Préparer la vue, créer un nouveau fichier Register.html sous appviews, le contenu clé est le suivant
<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}} …
Expliquez petit à petit les mots-clés bleus ci-dessus signification.
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。
我们都知道用户注册的时候填写的值是需要做有效性检验的,当用户填写的值不符合标准时需要出现错误提示,通常来说会是下面这样
$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看看吧。是不是这样呢?
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语言教程栏目。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!