一、先测试看看效果
GitHub地址简单的注册与登录Server
你可以将我GitHub上的代码拷贝下来进行测试,也可以导入我的包进行测试,导入GitHub上的包,我写的有教程,请戳golang导入GitHub中的包;下面是我测试的代码:
package mainimport "github.com/wutiange/go/simpleHttp"func main() { simpleHttp.RunServer() }
看到上面的测试代码了没,只需要简单几行;请注意包的问题,如果有遇到包的问题,看我好友的教程Golang学习笔记之包(package)
我写的这个只支持POST方式,并且只接收json,而且是对象json,而不是数组json(你如果看明白了,可以自行修改测试),如果采用GET方式,可以使用request.FromValue("对应的名字"),在下面有说;接下来我会写一篇使用YARC! 进行调式的教程,到时候会把链接贴到这里,链接地址为:使用YARC进行测试。
传输数据格式:{"Username":"wujingyue","Password":"wujingyue"}
如果你是使用本机运行的,而且使用的是本机测试:
http://127.0.0.1:9000/login 进行登录
如果你是在像阿里云或者腾讯云这样的服务器上运行的;而你是使用你的电脑进行测试的,那么就使用:http://你的服务器地址:9000/register 进行注册
http://你的服务器地址:9000/login 进行登录
测试各种情况返回的结果:
如果注册成功返回的是:{"State": true,"Detail": "注册成功"}
如果注册失败,只有一种情况,那就是用户名相同,所以返回的是:{"State": false,"Detail": "用户名已存在"}
如果登录失败,有两种情况,你输入的用户名没有注册:{"State": false,"Detail": "用户名不存在"}
另一种情况:{"State": false,"Detail": "用户名或密码错误"}
如果成功:{"State": true,"Detail": "登录成功"}
二、接下来我们分析里面的函数
⒈ 我们先看RunServer函数:
func RunServer() { http.HandleFunc("/login", login) //登录 http.HandleFunc("/register", register) //注册 if err := http.ListenAndServe(":9000", nil); err != nil { fmt.Println("监听失败") } }
其中使用HandlerFunc与ListenAndServe函数需要使用官方http包,需要导入import "http";接下来看看这两个函数;
HandleFunc函数原型:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
其中:
第一个参数pattern就像是路径,但这儿跟路径又不同,也就是这里如果写了/register,那么在访问的时候需要使用,你部署这个Server的地址,如果是本地写127.0.0.1然后是冒号:端口号,最后就是设置的pattern值:127.0.0.1:9000/register;
第二个参数handler是一个回调函数,这个回调函数有两个形参,第一个形参是响应,也就是服务器可以给客户端发送信息,第二是请求,也就是服务器传过来的信息,像下面这种:
{
"method": "POST",
"transformRequest": [
null
],
"transformResponse": [
null
],
"url": "http://127.0.0.1:9000/login",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json, text/plain, /"
},
"data": "{"Username":"wutiange","Password":"123456"}",
"timeout": {}
}
我们可以通过第二个参数得到这里面的值,特别是data里面的数据。
ListenAndServe函数:
第二参数一般都是nil,第一个参数也就是地址,比如说:127.0.0.1:9000,如果像我上面那样写就代表着任何IP都可以访问,只要端口号对应,这个函数返回error,如果error不等于nil就代表失败;
这个函数的原型为:
func ListenAndServe(addr string, handler Handler) error
⒉ 接下来看回调函数
func register(res http.ResponseWriter, req *http.Request) { if req.Method == "POST" { //判断是不是POST请求 s, _ := ioutil.ReadAll(req.Body) //读取数据 Register(s) //注册 res.Write(Feedbook(status)) //注册的结果反馈给用户 } else { res.Write([]byte("{\"false\":\"只支持POST方式\"}")) } }
就看注册的这一个,其中
① req.Method查看的是使用哪一种方式,一般是GET或POST,如果采用的是GET,这里可以使用req.FromValue("对应的键")来访问,比如你的请求地址为:http://127.0.0.1:9000/login?Username=wujingyue&Password=123456;那么获取用户名只需要使用:req.FromValue("Username")就能得到wujingyue;
② s, _ := ioutil.ReadAll(req.Body) 将io中的数据转换成[]bu=byte;
③ res.Write(Feedbook(status)) 这个函数就是将里面的信息反馈给客户端,参数是一个[]byte;
⒊ 接下来我们看Register函数
func Register(userInfo []byte) { var user User json.Unmarshal(userInfo, &user) //将json转换成结构体 if Existed(user) { //判断是否已经注册过 status = Status{false, "用户名已存在"} //将状态回馈信息写入 return //一旦失败,程序就没必要再执行了 } user.Id = userId userId += 1 userArr = append(userArr, user) //将这个用户的信息保存到切片中 status = Status{true, "注册成功"} }
这个函数里面主要就是一些简单逻辑的处理,我需要说明的是将json转换成struct的函数Unmarshal,这个函数接收两个参数,第一个是[]byte,第二个是要将转换的结果保存到哪儿,我这里是保存到结构体中,所以写结构体的地址,这里需要就是地址,无论转换成什么都需要取地址,除非本来就是指针;与这个函数对应的是Marshal,这个函数是将golang里面的结构体,map,切片转换成json,这个函数只有一个参数,也就是一个上面三种中的变量,这里不需要取址,类型写的是空接口,但也不要将其他的传入到这个中;
注意:这两个json转换的函数,在对待struct的时候,需要结构体里面的属性首字母大写,否则会出现得到的是空,主要原因应该是外部访问,在golang中就是需要将其写成大写;
Marshal函数的实例在Feedbook函数中。
作者:吴敬悦
链接:https://www.jianshu.com/p/623abb4bd049