获取GET
请求参数
Server:
// 获取GET请求数据
server.BindHandler("/", func(r *ghttp.Request) {
// 简化参数获取,GetRequest*的别名
r.Response.Writeln(`r.Get("name")->`, r.Get("name"))
r.Response.Writeln(`r.GetInt("age")->`, r.GetInt("age"))
r.Response.Writeln(`r.GetFloat32("weight")->`, r.GetFloat32("weight"))
r.Response.Writeln(`r.GetVar("age").Int()->`, r.GetVar("age").Int())
// 获取GET方式传递过来的参数,包括Query String及Body参数解析
r.Response.Writeln(`r.GetQuery("name")->`, r.GetQuery("name"))
})
执行请求:
fanhaodeMacBook-Pro:~ fanhao$ http http://127.0.0.1:8080 name==admin age==23 weight=77
HTTP/1.1 200 OK
Content-Length: 120
Content-Type: text/plain; charset=utf-8
Date: Thu, 09 Jan 2020 06:18:25 GMT
Server: GF HTTP Server
r.Get("name")->admin
r.GetInt("age")->23
r.GetFloat32("weight")->77
r.GetVar("age").Int()->23
r.GetQuery("name")->admin
获取POST
请求参数
// 获取POST请求数据
server.BindHandler("POST:/post", func(r *ghttp.Request) {
// 获取表单方式传递过来的参数,
// 表单方式提交的参数Content-Type往往为application/x-www-form-urlencoded
// application/form-data, multipart/form-data, multipart/mixed等等
r.Response.Writeln(`r.GetForm("name")->`, r.GetForm("name"))
r.Response.Writeln(`r.GetForm("age")->`, r.GetForm("age"))
})
执行请求:
fanhaodeMacBook-Pro:~ fanhao$ http -f POST http://127.0.0.1:8080/post name=admin age=23
HTTP/1.1 200 OK
Content-Length: 46
Content-Type: text/plain; charset=utf-8
Date: Thu, 09 Jan 2020 06:26:21 GMT
Server: GF HTTP Server
r.GetForm("name")->admin
r.GetForm("age")->23
获取任意提交方式的请求数据
server.BindHandler("/test", func(r *ghttp.Request) {
r.Response.Writeln(`r.GetRequest("name")->`, r.GetRequest("name"))
r.Response.Writeln(`r.GetRequestInt("age")->`, r.GetRequestInt("age"))
})
执行 GET
请求
fanhaodeMacBook-Pro:~ fanhao$ http http://127.0.0.1:8080/test name==admin age==23
HTTP/1.1 200 OK
Content-Length: 55
Content-Type: text/plain; charset=utf-8
Date: Thu, 09 Jan 2020 06:29:50 GMT
Server: GF HTTP Server
r.GetRequest("name")->admin
r.GetRequestInt("age")->23
执行POST
请求
fanhaodeMacBook-Pro:~ fanhao$ http -f POST http://127.0.0.1:8080/test name=admin age=23
HTTP/1.1 200 OK
Content-Length: 55
Content-Type: text/plain; charset=utf-8
Date: Thu, 09 Jan 2020 06:31:18 GMT
Server: GF HTTP Server
r.GetRequest("name")->admin
r.GetRequestInt("age")->23
参数绑定到struct
server.BindHandler("/struct", func(r *ghttp.Request) {
// 将指定类型的请求参数绑定到指定的struct对象上
type User struct{
Name string
Age int
}
var user User
err := r.GetStruct(&user)
if err != nil {
panic(err)
}
_ = r.Response.WriteJson(g.Map{
"name": user.Name,
"age": user.Age,
})
})
执行请求
fanhaodeMacBook-Pro:~ fanhao$ http http://127.0.0.1:8080/struct name==admin age==23
HTTP/1.1 200 OK
Content-Length: 25
Content-Type: application/json
Date: Thu, 09 Jan 2020 06:31:59 GMT
Server: GF HTTP Server
{
"age": 23,
"name": "admin"
}
获取客户端提交的原始数据
server.BindHandler("/get_body", func(r *ghttp.Request) {
// 获取客户端提交的原始数据,该数据是客户端写入到body中的原始数据,与HTTP Method无关,
// 例如客户端提交JSON/XML数据格式时可以通过该方法获取原始的提交数据。
r.Response.Writeln(`r.GetBody()->`, r.GetBody())
r.Response.Writeln(`r.GetBodyString()->`, r.GetBodyString())
})
同名参数优先级问题
// 同名参数优先级问题
// Router < Query < Body < Form < Custom
server.BindHandler("/get_params", func(r *ghttp.Request) {
r.Response.Writeln(`r.Get("name")->`, r.Get("name"))
r.Response.Writeln(`r.GetQuery("name")->`, r.GetQuery("name"))
})
执行请求:
fanhaodeMacBook-Pro:~ fanhao$ http -f POST http://127.0.0.1:8080/get_params name=admin name==zhangsan
HTTP/1.1 200 OK
Content-Length: 50
Content-Type: text/plain; charset=utf-8
Date: Thu, 09 Jan 2020 06:40:22 GMT
Server: GF HTTP Server
r.Get("name")->admin
r.GetQuery("name")->zhangsan
同名参数
同名参数提交格式形如:k=v1&k=v2 ,后续的变量值将会覆盖前面的变量值。
server.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writeln(`r.Get("name")->`, r.Get("name"))
})
执行请求:
fanhaodeMacBook-Pro:~ fanhao$ http http://127.0.0.1:8080 name=admin name=zhangsan
HTTP/1.1 200 OK
Content-Length: 24
Content-Type: text/plain; charset=utf-8
Date: Thu, 09 Jan 2020 06:44:02 GMT
Server: GF HTTP Server
r.Get("name")->zhangsan
数组参数
server.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writeln(`r.Get("users")->`, r.Get("users"))
})
执行请求:
r.Get("users")->["admin","zhangsan"]
Map参数
Map
参数提交格式形如:k[a]=m&k[b]=n
,并且支持多级Map
,例如:k[a][a]=m&k[a][b]=n
。
server.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writeln(`r.Get("map")->`, r.Get("map"))
})
执行请求:
127.0.0.1:8080/?map[name]=admin&map[age]=23&map[server][host]=127.0.0.1&map[server][port]=80
r.Get("map")->{"age":"23","name":"admin","server":{"host":"127.0.0.1","port":"80"}}
Parse 参数解析到结构体
// 请求参数结构体
type UserReq struct{
Name string `param:"name" json:"name"`
Age string `param:"age" json:"age"`
}
// 返回参数结构体
type UserRes struct{
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// 使用Parse方法来实现struct的转换
server.BindHandler("/", func(r *ghttp.Request) {
var userReq UserReq
if err := r.Parse(&userReq); err != nil {
_ = r.Response.WriteJsonExit(UserRes{
500,
err.Error(),
nil,
})
}
// 正常返回
_ = r.Response.WriteJsonExit(UserRes{
Code: 200,
Msg: "",
Data: userReq,
})
})
执行请求:
127.0.0.1:8080/?name=admin&age=23
{
"code": 200,
"msg": "",
"data": {
"name": "admin",
"age": "23"
}
}
参数校验
// 请求参数结构体
type UserReq struct{
Name string `param:"name" json:"name" v:"required|length:6,30#请输入名称|你的长度不够:min位-:max位"`
Age string `param:"age" json:"age" v:"required|integer#请输入年龄|请输入数字"`
}
// 返回参数结构体
type UserRes struct{
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// 使用Parse方法来实现struct的转换
server.BindHandler("/", func(r *ghttp.Request) {
var userReq UserReq
if err := r.Parse(&userReq); err != nil {
_ = r.Response.WriteJsonExit(UserRes{
500,
err.Error(),
nil,
})
}
// 正常返回
_ = r.Response.WriteJsonExit(UserRes{
Code: 200,
Msg: "",
Data: userReq,
})
})
执行请求:
127.0.0.1:8080/?name=admin&age=23abc
{
"code": 500,
"msg": "你的长度不够6位-30位; 请输入数字",
"data": null
}
127.0.0.1:8080/?name=admin&age=23
{
"code": 500,
"msg": "你的长度不够6位-30位",
"data": null
}
127.0.0.1:8080/?name=admin001&age=23
{
"code": 200,
"msg": "",
"data": {
"name": "admin001",
"age": "23"
}
}
两次密码相同校验
// 请求参数结构体
type UserInfoReq struct{
Username string `p:"username" json:"username"`
NewPassword string `p:"new_password" v:"required" json:"new_password"`
ChkPassword string `p:"chk_password" v:"required|same:new_password#请再次输入密码|两次输入的密码不一致" json:"chk_password"`
}
// 响应结构体
type UserInfoRes struct{
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// 参数验证
server.BindHandler("/check", func(r *ghttp.Request) {
var req UserInfoReq
if err := r.Parse(&req); err != nil {
_ = r.Response.WriteJsonExit(UserInfoRes{
500,
err.Error(),
nil,
})
}
// 正常返回
_ = r.Response.WriteJsonExit(UserInfoRes{
Code: 200,
Msg: "",
Data: req,
})
})
执行请求:
127.0.0.1:8080/check?username=admin001&new_password=23&chk_password=231
{
"code": 500,
"msg": "两次输入的密码不一致",
"data": null
}
127.0.0.1:8080/check?username=admin001&new_password=23&chk_password=23
{
"code": 200,
"msg": "",
"data": {
"username": "admin001",
"new_password": "23",
"chk_password": "23"
}
}
转换错误对象
// 请求参数结构体
type UserReq struct{
Name string `param:"name" json:"name" v:"required|length:6,30#请输入名称|你的长度不够:min位-:max位"`
Age string `param:"age" json:"age" v:"required|integer#请输入年龄|请输入数字"`
}
// 返回参数结构体
type UserRes struct{
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// 使用Parse方法来实现struct的转换
server.BindHandler("/", func(r *ghttp.Request) {
var userReq UserReq
if err := r.Parse(&userReq); err != nil {
if v, ok := err.(*gvalid.Error); ok {
_ = r.Response.WriteJsonExit(UserRes{
500,
v.FirstString(),
nil,
})
}
}
// 正常返回
_ = r.Response.WriteJsonExit(UserRes{
Code: 200,
Msg: "",
Data: userReq,
})
})
执行请求:
127.0.0.1:8080/?name=admin&age=23abc
{
"code": 500,
"msg": "你的长度不够6位-30位",
"data": null
}
127.0.0.1:8080/?name=admin123&age=23
{
"code": 200,
"msg": "",
"data": {
"name": "admin123",
"age": "23"
}
}
上下文变量
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
// 中间件1
func Middleware1(r *ghttp.Request) {
r.SetParam("name1", "001")
r.Response.Writeln("set name1 001....")
r.Middleware.Next()
}
// 中间件2
func Middleware2(r *ghttp.Request) {
r.SetParam("name2", "002")
r.Response.Writeln("set name2 002...")
r.Middleware.Next()
}
func main() {
s := g.Server()
s.Group("/api", func(group *ghttp.RouterGroup) {
// 使用中间件
group.Middleware(Middleware1, Middleware2)
group.GET("/hello", func(r *ghttp.Request) {
r.Response.Writeln(`r.GetParam("name1")->`, r.GetParam("name1"))
r.Response.Writeln(`r.GetParam("name2")->`, r.GetParam("name2"))
})
})
s.SetPort(8080)
s.Run()
}
执行请求:
127.0.0.1:8080/api/hello
set name1 001....
set name2 002...
r.GetParam("name1")->001
r.GetParam("name2")->002
Exit返回方法
Exit
: 仅退出当前执行的逻辑方法,不退出后续的请求流程,可用于替代return
s.BindHandler("/hello", func(r *ghttp.Request) {
r.Response.Writeln("aaa")
r.Exit()
r.Response.Writeln("bbb")
})
执行请求:
127.0.0.1:8080/hello
aaa