獲取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"))
})
執(zhí)行請求:
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"))
})
執(zhí)行請求:
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"))
})
執(zhí)行 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
執(zhí)行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,
})
})
執(zhí)行請求
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())
})
同名參數優(yōu)先級問題
// 同名參數優(yōu)先級問題
// 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"))
})
執(zhí)行請求:
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 ,后續(xù)的變量值將會覆蓋前面的變量值。
server.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writeln(`r.Get("name")->`, r.Get("name"))
})
執(zhí)行請求:
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"))
})
執(zhí)行請求:
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"))
})
執(zhí)行請求:
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,
})
})
執(zhí)行請求:
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,
})
})
執(zhí)行請求:
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,
})
})
執(zhí)行請求:
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,
})
})
執(zhí)行請求:
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()
}
執(zhí)行請求:
127.0.0.1:8080/api/hello
set name1 001....
set name2 002...
r.GetParam("name1")->001
r.GetParam("name2")->002
Exit返回方法
Exit: 僅退出當前執(zhí)行的邏輯方法,不退出后續(xù)的請求流程,可用于替代return
s.BindHandler("/hello", func(r *ghttp.Request) {
r.Response.Writeln("aaa")
r.Exit()
r.Response.Writeln("bbb")
})
執(zhí)行請求:
127.0.0.1:8080/hello
aaa