00:00
花了时间,好,我们来开始写这个东西,下面呢,我们完成第二步,就是如果输入的用户名和密码正确,在ready中,就是你输入的用户名和密码就就在在这个RA中,则存在就登录成功,否则就退出系统,并给出相应的提示。什么信息呢?就是一种是用户不存在或者密码错误,还有一种呢,就是就是还有一种就是你这个再给他提示,你可以重新注册再登录。对吧,这个就可以给他提示相应的错误信息了,好,我把这个呢进行一个完整。好,把它的诗意分析放到这儿了。往这一写好,然后呢,这边可以给他提示相应的信息。给他相提示相应的信息,什么信息呢?就是这样的一些信息,用户不存在对吧,登录的时候,你有可能是因为你的用户不存在,也有可能是你的密码不对,这个呢,你可以分成两种形式提示,比如第一种是用户不存在。
01:03
你可以这样写,用户不存在,还有一种,还有一种可能性呢,就是立马写错了,你如果愿意分开提示也可以,就是用户不存在,那你就直接提示这句话。提示这句话就说用户不存在,你可以重新,你可以重,你可以重新注册再登录,还有一种就是你的密码不正确,是你的,比如说还有一种情况是你的密码。密码不正确不正确对吧,可以这样提示好。可以了。好,这个这个提示信息,这就完了,然后呢,我们代码实现它一下。代码实现。好代码实现呢,我们就看这个具体的步骤,一步一步的做啊。好,嗯,代码实现建立在哪个基础之上呢?就建立在我们这个程序的分析基础之上。程序的分析基础之上。好,这就可以就可以来开始玩了啊。
02:01
OK,那现在怎么写呢?就按照刚才这个设计,一步一步往里面写,打开我们的这个幻灯片,我们来看一下,到现这个程序的结构呢,是这样子的,就是新增三个文件,然后呢,这个red在这里生生生成,好,我们现在就开始写。呃,先写哪个比较好呢?哪个写的比较好呢?我们要不这样写啊,先把这个model这一块的三个文件写完。然后呢,我们再去学这个re。这个RA,这个RA呢,它是属于一种初始化的信息说这个文件,这个文件可以直接放在main这个文件夹下面。啊呃,放在main这个文件夹下面这个这个位置呢,可以可以根据自己的实际需要放在相应的位置,好那我就这样写了,打开它,然后呢,找到server这一层,别别找错了啊,然后model现在什么都没有,现在开始写东西了,第一个。
03:00
我们新增加一个文件,叫users。UR点勾第一个文件,第二个文件,第二个文件呢是用来专门自定义错误的error,点勾第三个文件就是专门用来操作user这一个结构体的,或者说磁力的user do。动DNA订购。好,基本上就差不多了,我们把这个写好点,够少写了一个。好,那么先写哪一个呢?先写user package走了啊,Model model先定义一个,或者是声明一个啊,定义一个用户的,用户的什么呢?用户的一个结构体。用户的一个结构体,那用户的结构体咱们怎么写呢?非常简单,Type user。User。帮起来。我们至少现在需要这样一些字段。先确定字段。
04:02
确定字段信息,哪些字段我们需要呢?哪些字段我们需要呢?第一个就是user ID。URID是一个int类型,第二个是用户的密码,密码呢是一个寸类型,第三个是用户的名字,是一个类类型,所是写完了。大家看,如果我这样写一个user这么一个结构体,我的问题就很严重了。为什么这么说呢?同学们可以看到,因为将来这个user一定会被反序列化或者序列化操作,而我们现在往这里面添加的这个序列化的这个UR,你们可以看到它的名字是小写的。他的这个前面的这个K是小写的,因此你在反序列化的时候,根本就序列化不会成功。因此你这边必须给我把这个T写进去,也就是说你必须要这么写了,Jason走冒号这个地方,这个UID,将来你会把这个反序列化的字符串付给哪一个字段,你就得根据这个信息给它匹配上哦。
05:15
这点特别的重要,如果你不注重这个细节,代码写不下去。但是这个坑。说实话,如果老师不给你们说,你们基基本上就是我可以肯定的是,咱们咱们这个第一次写的同学,基本上百分之八九十都会踩这个坑,因因为一般同学不会不会考虑这么多信息。啊,所以说呢,这个我们一定要把这个他加进去,这段为了说句话啊,为了能够序列化或者反序列化成功,为了序列化。序列化,序列化和反序列化,反序列化这个成功我们必须保证,我们必须保证,保证什么东西呢?就是你这个地方的就是字符串,就字符串的那个K,就是那个GS,那个K要跟这个T要对应,不然的话序列化不会成功,就是字符串。
06:11
就是用户。用户。用户信息的那个字符串,字符串它的那个那个接省字串啊,当然肯定是字符串,就是接省字串,接省字串的KK和。和和我们这个结构体的结构体的字段对应的这个tag。就是的名字保持一致,名字一致,否则就一定会失败的,否则会失败啊。写到这里。好,写到这里。好,呃,那么我现在这个地方就可以写成U了,UID注意跟上思路啊,这代码量比较大,可能是得写一会接省。
07:00
节省中。然后呢,这边应该写成UR密码。这个地方也一样,跑不了,叫杰森招。然后呢,User name。OK。好,这写完了,好写完过后呢,我这地方再插一句话啊,先这样打住,我先插一句话,嗯,这个地方有一个地方我要跟他说清楚,同学们可以看到我这个服务器这边呢,大家如果学过MVC的同学呢,可能感觉到,诶他说韩老师你认为是不是少了一层。你看啊,现在这一块呢,是我们的控制层,相当于是这个CMVC里面的那个C这一层是model层,相当于是M,那你那个MVC,那你这个,那那你这个界面界面上哪去了呢?对吧,我我界面你可以理解成就就它能理解吧,你可以理解成就他理解,因为你见面不就是main main来显式的吗?还有呢,有些同学学过MVC还说诶韩老师,我以前学学这个MVC的时候,我听说都有一个service层。
08:08
就是那个服务层,服务层这个有没有呢?其实是一般来说都会有的,对于一些比较复杂的项目都会有一个service层,但是因为我目前这个项目比较简单,所以这个service层我就没有用了,要理论上应该是这样子的啊,一个标准的一个MV,它应该是这有个中间还有一层。但是我们这个项目太小了,还谈不上这个东西,就说按理说是这样子的。就说应该标准的一个结构啊,同学们都学过,因为我们好些听课的学生呢,都学过这种一些一些项目嘛,学过一些语言,他说诶这个这个控制去掉呢,一般会先调service层。这个service层,那SERVICE10层呢,再去调我们model层一般是这种结构,但是现在呢,我为什么没有写这个service,我可以留一个接口在这,我可以留一层在这,但是我先暂时不用,因为我现在这个功能很简单,什么时候会有service层呢?就是当你这个业务很复杂。
09:10
你这个service之间。你这个service之间会相互调用,或者是一个service的一个业务会调用到多个道来完成的时候,咱们才会有service层,不然的话实际上是这个service尺层呢,简单的情况下一个道就可以处理完了,明白我意思吧,但是你以后也不复杂的时候,你可以加一层。现在呢,暂时用不上,我就先暂时不写这一层,我先把这个道理给你说清楚啊,不然有些同学做个开发,他说诶不,韩老师少写一层对不对,好明白这意思啊,那个内存可以随时的给他搞进去啊,随时可以搞进去,那现在呢,我因为业务比较简单,就暂时不写了,什么时候用呢?比如说你将来涉及到比如说。转账就是这个要调那个或者是订单,我要去调第三方的一个一个service,诶那个时候可以再加一层,但现在业务比较简单,我暂时没有写,但是我可以留下来啊,也就是说如果说我留下来的话呢,我应该在这个service这边呢,再加一个,加一个包包叫service。
10:13
但这里面现在暂时是空的啊,暂时是空的,能理解我的意思啊,各位朋友好了啊,这个呢,我们接着写啊,我们接着写,把刚才把这个思路给大家再说了一下,捋了一下啊。啊,怎么这么渴呀?啊猴口水精神好多了,那接着往下整啊,那现在呢,我已然把哪块写完了,把这个U搞定对不对,那现在呢,我们再把这个error搞定好吧,把error搞定就是就是将来我们在登录的时候或者注册的时候有各种错误啊,有各种错误,比如说诶用户已经存在了。这是一种错误,还有一种诶,比如说打个比方,用户不存在是一种错误,还有一种用户存在也是一种错误,打个比方,你将来注册,你注册这个ID已经存在了,它也是一种错误,我就把这个用户ID已存在给他返回去,好,那么现在第二步我们又写这个error.go。
11:12
好,那同学们还找到它来写吧。Package,呃,就是猫豆。Model没问题,那这个时候呢,我们自定义一些。就根据业务逻辑。注意听啊,根据根据业务逻辑的需要,需要自定义自定义自定义一些错误,一些错误,但这个错误呢,完全由我们程序员来控制,你想定义哪些错误,你就写哪些错误好,那么我们就这样写了,把它定义成常量啊,把定义成这个常量。对,把它定义成常量constant,呃,那么这个我们先定义成变量吧,到时再改一下啊,现在一时半会先写一下。
12:01
好,呃,常量我们先这样做,呃,因为它是要做成全局的,我要以些包包,我要以些包包,好,首先我肯定要以这个aros。L是一个包,那这个时候呢,我就定义这么几个,第一个呢,就是用户还没有存在,第二个是用户已存在,还有一个密码无效的密码,我写几个这样的啊,就是什么L。什么错误呢?User啊,这样子你为了好看,可以可以这样子打一个杠杠号啊,Error user存在了啊,Not not啊。A note。Not e nots啊,Exist存在啊,就是这个地方,我们写一个NEW1啊,就是arrow errorrs点。六。另一个什么呢?就是这样一个信息,就说该用户用户不存在,用户不存在。
13:05
不存在啊,类似于这样一个错误信息,那么还有呢,还有一个error,比如说L下划线,为了好看一点,Userr什么呢,已经存在了eississ,呃,就是说有时候这个存在也是一种错误,什么时候会是一种错误呢?打个比方,你在注册的时候,你注册的时候你只定了一个ID,对吧,这个ID人家已经占用了,你说我要我要注册一个200号的ID没有啊,所以说这个也有可能说就errors。As点6.6,那么这个时候呢,我们给他返回一个信息,就是用户已经存在,用户已经存在,OK,好,那还有一种什么错误呢?就是比如说你输的密码不正确,对不对,你的密码不正确,我们写个error error叫什么呢?叫做user的密码错误了,User的密码密码PWD简简写啊同学们,那errorrs点261个就说密码无效或者密码不正确。
14:10
密码不正确不正确,写完了好保存一下。好保存一下,看看这个user里面还有错误信息啊,这个错误信息是因为可能是因为什么原因,我先保存一下。Package model。好。啊,有到有到里面还没写东西来,现在呢,自然我现在已经完成了UGO,还完成了error.go那现在自然到了这个U到了。U道,那么这个U2道你得分析出来,他应该给我们提供什么样的方法呢?好,这里面的内容就有点多了啊,这内容肯定要写一会,那么来分析一下他应该给我们提供哪些方法来package。Package,然后呢,写个包包叫model包啊,那这个时候呢,肯定会引一些东西在里边先写上。
15:06
好,我们先说明一下它是干什么的,就说该user就是这里定义一个。定义一个user到这么一个结构体。结构体,它完成什么任务呢?他要完成对完成对user。这个结构体的各种操作,各种操作啊,比如说啊,一个添加呀,或者一个登录啊,或者一个注册呀,咱可以简单写到这里来。那怎么怎么写呢?各位朋友,那先定一个结构体吧。那type type user动。有点冻。好,有点逗,然后呢,我这边把它整成一个结构体structure。它里面需要什么信息呢?对于这个user来说,它需要什么东西呢?大家可以想一想,哎,Userr到,诶想一想,因为这个UR到它最终它是要去操作我们这个可爱的red的,那既然你要去操作这个red,那你应该至少有一个字段,它能够很轻松的拿到这个连接词。
16:16
对,他要拿到这个连接词,那干脆这样子,我们上来过后呢,就把这个连接词作为它的一个字段塞给他,你需要你就去取就完事了。就说上来之后就把连接词直接做一个字段付给他了,好,那我的思路就这样来了,啊同学们,那我这样做。我怎么做呢?我做一个这样的东西。它有一个字段啊,它有个字段叫破这个。这个这个破的类型呢,这个破的类型是什么呢。是这个包包里面的这个。好。他有这个,那同学们回忆一下啊,回忆一下这里面有个要领,一个RA这个包里面我们看一下,当时我们在开发这个ready的时候,我们讲了哪些内容,是第19章的时候,我们讲过一些关于连接词的使用,来我们lawyer。
17:20
我们来搂,在18章里面,我们有一个ready poor这个玩意儿,拿过来用用吧,不用再去动脑筋了啊,因为你自己写过的东西,你没有必要每每次都来玩一把对不对?好,我们先顶一个全局的扑。先第一个全局的per,好,那这个是这个全局per呢,到时间我们放在哪里比较合适啊,先不别放这,先别放这,这个呢放在这个Dis点,把这个per放在个red.go里面比较合理,所以说这先不放,那到时间呢,我们这个地方把这个路径先引进来,这个是我们需要用到的red的第三方插件啊,所以这个呢,我们是需要的来往这扔一下啊,动脑筋。
18:01
动脑筋,好扔过来,扔过来。好的保存一下,那就在它这有个破破二的类型呢,就它好这就没问题了,那现在我们开始写方法了啊写方法。说老师,那这个幼儿道里面有哪些方法呢?那我们来动动脑筋想一想,想一想啊,我们思考一下,我们思考。思考一下。就是在。在这个就是在这个user到里面,他应该提供哪些方法给我们。应该提供提供哪些方法给我们呢?哎,你动脑筋了。我个人感觉有这么几个方法啊,至少第一个是这样子的。大家琢磨琢磨,待会儿呢,我们要去完成一个登录,我们既然要去完成一个登录,首先你们肯定会有一个登录的方法要给我。我把我把这个拿到的用户名和密码,我把拿到的用户ID和密码传给你,你就得告诉我这个用户存在还是不存在,或者是有什么错误,这是你第一个要给我的事情,第二个你至少还要应该有一个能力,我给你传一个ID,你能不能返回一个用户的这个实力。
19:19
如果没有的话,你给我返回一个error,说这两个方法是必须的,所以说类似于这样一个东西。类似于这两个方法,我们要分析出来啊,第一个方法呢,第一个就是第一个啊,这个要思考就是根据。根据一个用户ID返回,返回一个一个user的实例。返回一个UR实例加L。就是如果你没有这个,没没有这个,那你就把L反馈过来,这第一个,那类似于这个方法,就应该是这样的一个方法啊,放走。This share注意听啊,同学们,老师再教大家怎么写啊,干脆这个地方我们就一般来说这个就叫倒吧啊,然后呢,这个地方我们就要get user by ID啊,Get user by ID,那你就给我传一个什么玩意过来呢。
20:16
ID号,你给我传个ID号就可以了,当然这个时候这个连接呢,你也可你也可以给我传个链接过来啊,当连接这里面其实也有也可以不传。也可以不传,我们先写一个在这啊,假设有链接不需要我们再把它删掉就行了啊,Connect理论上是需要一个连接,只是这个链接呢,有可能他这方也可以拿到啊,也可能是别的地方传给我的,都有可能都有可能好,那这个时候呢,我们把这个链接先拿到,叫connect。啊叫net.connect好的,然后呢,你再给我传一个用户的ID没问题吧,那就给我一个ID,这个ID呢,咱们就叫int就可以了。好,最后如。
21:02
啊行,我先写到这,待会再修改一下,好red connect,他说connect到时我从这直接取吧,我其实我我知道这个有一个问题啊,其实这个地方我是最后这个连接我是从哪传的呢?是从这个坡里面,坡里面给它塞过去的。还是从这个破里面给塞过去的,只是在什么时候塞呢?在登录的时候,我会从我会从那个登录函数里面去掉它。然后会传给他啊,待会写到这大家就知道了,大家就知道了啊,我先留在这个地方,留个小问题好,最后呢,嗯,要返回两个信息,一个呢,就是把这个user给我,给我返回,那user呢,我们返回的应该是个什么呢?哎,User我们返回一个这样的东西,就是这个user类型啊user OK。那这个地方我们来一个引用也可以啊,来一个引用,然后呢,这边呢,有个L啊L。
22:01
好,可以了。好,那现在呢,我们来写一写啊,来写一写,就是我们现在假设已经有了连接con con有这个连接,有这个ID了,我们怎么去查询它呢。怎么去查询它呢,就说现在我们怎么去查询它呢,这是一个啊,就是通过通过这个给定的给定的。给定的这个这个ID去。啊去哪里呢?去这个连接词去啊去red里面去查询RA查询。查询这个这个用户。用户。好。嗯,大家回忆一下,我们当时去操作的时候啊,我们是有了连接其实就已经可以做事情了,有了连接其实就可以做事情了,怎么做的呢?Conn点儿。它里面呢,哦,对,刚才那个给我说错了,我我自己搞错了啊,刚才那个说的很都很对,这个应该是应该是不是这个连接啊,写写错了,应该是这个连接,对刚刚才那个,呃,刚才那个。
23:11
呃,同学说的很对,应该是这个连接是。是里面的一个是吧。是怎么写的那个。是这样写的吧,对对对对对,是我刚才搞错了啊,是我搞错了,这这个才对啊,这个才对,没错啊,是这个吧,我们以前我们以前在操作的时候,在第18章时候,我们写的时候,大家可以看到也是这么去操作的,我们是从它获取了一个破是吧,获取了破以前最原始的时候,我们是怎么操作的呢?看在。在ready第二个案例的时候,我们也写了这样的类似的操作,你看我们是怎么做的,是red style里面拿到一个连接,对不对,拿到链接,但这个连接,这个连接是拨号拿到的,但这个类型呢,还应该是RA里面的一个connect啊,Connect这个。
24:03
跟我们网络连接是两回事,对,刚才说的很对啊,好,我再重新来玩一把,好,好,现在有了这个连接过后呢,我们调查的一个方法叫do。那do的时候怎么do呢?首先我写个h h get h,然后我要去查询的这个K,它叫users啊,就这个哈希,哈希它的名称叫users里面呢,要传的是要要把通过这个ID来获取。好的,那这边呢,整个会返回一个字符串,所以说我用red。写的很对。包起来。包起来,然后呢,这边会返回一一两个两个这个结果,一个是read res,一个是L。一个是L,好的,那现在呢,我可以做一个小小判断,如果,如果这个A不等于near。
25:02
不等于零二啊,说明我们这边有问题就出错了,这个有错误。那么什么错误呢?什么错误呢?好,同学们可以看到啊,RA里面有一个错误,这个RA里面有个错误,如果error,它等于这样一个错误。叫ready.eril我记得是这个啊,如果是这个错误,其实就代表我们没有查到,就是这个ID是不存在的,再说一遍啊,我我再看一下这个,我再看一下这个有有有点有点记不住了,我看一下啊啊eril对没错没错,ER。没错啊,我把这个再回头再写到这边来。没错没错,如果是这种错误呢,表示什么意思,我说一下表示就是在哪里呢?在这个users这个哈希哈希中。
26:04
这个哈希中。哈希中,我们没有找到对应的ID,没有找到对应的这个ID,就说没有这个人在。那如果没有这个人在呢,就比较简单了,我们直接把这个L复制一个我们已经创建好的,已有的一个L信息,就是该用户不存在,直接复制给他。好,那这个时候呢,整个就可以了,不玩了。Return谁呢,就直接就可以了。就把成,那否则的话我们要继续玩啊,继续玩,因为你如果这个没问题的话。就说你这个代码没有问题,说明至少这个用户是存在的。那么这个用户存在,这个用户存在你就去干什么呢?要去比对他的这个密码是不是合适的了,对吧?好,那现在呢,还没到那个比对密码的时候,因为你现在还没有办法。
27:04
把这个东西反序列化,所以说你现在还要做一件事情,干什么呢?这里要做一件事情。这里我们需要把。把什么呀,这个res反序列化成反序列化,注意听反序列化。成一个UR对象。有点实力。这个大家可能不能理解,因为你到时间这个ras取出来的东西呢,其实长得就是这个样子的。长得就是这个样子的。这个肯定是大家能够想到的,就你讲的就是它,但是这个东西没有用,你得把它先序列反序列化成U的实例,我们才能够取出它对应的ID和他的密码,是这意思吧,OK,好,现在呢,我们要把它版序列化,这个也很简单。怎么反序列化呢?因为你这已经有这个东西了,我就直接用它来玩一把。来,走,有点。
28:00
呃,这样子啊,嗯,你这样写就是杰森。Jason。Jason。点on Mar跟上我的思路。Martial martial,然后呢,首先第一个参数就是这个字符串对应的字解码。但这个自检码也很好找到直接,呃,这这个BY切片啊BY切片那就是这样子的转。Bye。然后呢,把这个字符串写进去啊,就是我们RS转成它,转成它过后呢,再把这个UR扔进去。再把这个userr扔进去,好这样子的话呢,就OK了,好这样,但这样子也可以,这样子做也安全一点啊,如果这样做的话,我们这样写应该更更更好一点,你传过来,因为传过来应该是一个具体的已经实例化的一个东西,你不能传一个指针,传一个指针,我没办法实例化,应该他他到时先这命名的是一个userr的一个实例,然后呢,我把这个传进去,让它复制完了过后,这个才是,呃,正确的,应该这样写才是合理的,对吧?好这个做完了以后呢。
29:12
就来把这个可以返回了,就说至少到这一步,我们可以肯定一点,就是说你的这个用户是有的,但是密码对不对我不知道。所以在这个时候呢,我们可以拿到一个error信息。如果你这样的话不行。哪个地方不行?然后你应该是在里面挂一个。你的实力,然后。把,那么你的实力。然后你传的。把那个实例的那个地址返回去给那个。这样的话,那你每一次返回去的话,就是一个新的。你就你就投资了。
30:00
哦,不不对是吧,这样子肯定不对啊。不不对是吧,大家觉得这样子,那就是还是我原先那个写的是对的是吧,这样这样写是对的吧里这样这样子行不行呢?这样子行不行,那就这样这样子啊,就U热一下,U热一下等于。是这样子的吧,你的意思就是说,对这样子也行啊,就是先你给我传了一个指针进来,我先把它给给它一个真正的一个指向,对不对,User等一下我现在写user。啊,它这个是地址吗?我传给他一个地址嘛,这个userr,然后里边相当于什么,我也不给他赋值,我也不给他赋值。就是说相当于把它给他了,给他了好这地方是不是有这样一个这样一个作用。对吧,给他那这份是已经有了,就不需要了吧,是不是这就不需要了呀,因为上面经有了嘛,就相当于把它给他创建,是创建了一下这个空间,然后这边还是传给他,这样就可以了吧,应该。
31:07
这样可不可以?这样不行吗?难道这还不行,因为你这样子的话就。那还不行吗,可以。这样这样可以的吧,应该这样可以的,就是我把我在里面给他把一个内存的,是给他一个真正的指向一个地址空间嘛,然后再把这个传进去,这是本身是个地址嘛,应该没问题吧。好,应该没问题,好先写着如果A不等于不等于near,如果它不等于near的话呢,我们怎么办呢?我们怎么办,就给他打印出一个消息,就是说你序列化反序列化出错了。Jason,反序列化出错。好。反序列话出错,那么错误的信息呢?给它打印出来,L等于找L就。
32:03
啊。好,我们保存一下,保存一下好下面有个错误是吧,他说没有引这个包包,我们把这个包呢引一下叫coding。Coding找杰森。好,再来看一下。好,这个函数现在。现在这个函数看到你还有问题。函数还有哪个地方有问题,他应该少了一个return,他说最后少了一个return,再来return一下,因为他担心你没有进到一,没有进到if里面去,好,这样子应该是可以的。好,这是我们相当于是第一段代码吧,代码还有很多,我们先把它实现成第一步,先执行一个,好先把这一块呢,先给大家讲到这。
我来说两句