goframe与gin对比(三) 请求输入

请求输入

复杂参数

同名参数

同名参数提交格式形如:k=v1&k=v2, goframe是后续的变量值将会覆盖前面的变量值,而gin因为用的标准库net/http, 提交的同名参数将会被转换为字符串数组。

package main

import (
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
)

func main() {
	s := g.Server()
	s.BindHandler("/", func(r *ghttp.Request) {
		r.Response.Write(r.Get("name"))
	})
	s.SetPort(8199)
	s.Run()
}

访问http://localhost:8199/?name=john&name=smith, 得到smith

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		name := c.Query("name")
		nameArray := c.QueryArray("name")
		c.String(http.StatusOK, fmt.Sprintf("hello %s ", name))
		c.String(http.StatusOK, fmt.Sprintf("hello %s %s", nameArray[0], nameArray[1]))
	})
	r.Run()
}

访问http://localhost:8080/?array=john&array=smith, 得到hello john hello john smith

数组参数

数组参数提交格式形如:k[]=v1&k[]=v2, goframe 与 gin 相同

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		// http://localhost:8080/?array[]=john&array[]=smith
		array := c.QueryArray("array[]")
		c.String(http.StatusOK, fmt.Sprintf("hello %s %s", array[0], array[1]))
	})
	r.Run()
}

访问http://localhost?array[]=john&array[]=smith, 得到["john","smith"]

package main

import (
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
)

func main() {
	s := g.Server()
	s.BindHandler("/", func(r *ghttp.Request) {
		r.Response.Write(r.Get("array"))
	})
	s.Run()
}

访问http://localhost:8080/?array[]=john&array[]=smith, 得到hello john smith

对象处理

可将数据解析与绑定分为 json, xml, 表单, uri 等几种。goframe和gin均支持这几种数据的绑定与解析。

goframe推荐使用 parse转换来实现struct的转换。可参考goframe请求输入-对象处理文档

package main

import (
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
)

type RegisterReq struct {
	Name  string
	Pass  string `p:"password1"`
	Pass2 string `p:"password2"`
}

type RegisterRes struct {
	Code  int         `json:"code"`
	Error string      `json:"error"`
	Data  interface{} `json:"data"`
}

func main() {
	s := g.Server()
	s.BindHandler("/register", func(r *ghttp.Request) {
		var req *RegisterReq
		if err := r.Parse(&req); err != nil {
			r.Response.WriteJsonExit(RegisterRes{
				Code:  1,
				Error: err.Error(),
			})
		}
		// ...
		r.Response.WriteJsonExit(RegisterRes{
			Data: req,
		})
	})
	s.SetPort(8199)
	s.Run()
}

访问http://127.0.0.1:8199/register?name=john&password1=123&password2=456, 得到{"code":0,"error":"","data":{"Name":"john","Pass":"123","Pass2":"456"}}

gin 和 goframe 类似

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

type RegisterReq struct {
	Name  string
	Pass  string `form:"password1" binding:"required"`
	Pass2 string `form:"password2" binding:"required"`
}

type RegisterRes struct {
	Code  int         `json:"code"`
	Error string      `json:"error"`
	Data  interface{} `json:"data"`
}

func main() {
	r := gin.Default()
	r.GET("/register", func(c *gin.Context) {

		var req RegisterReq
		if err := c.ShouldBind(&req); err != nil {
			c.JSON(http.StatusBadRequest, RegisterRes{
				Code:  1,
				Error: err.Error(),
				Data:  req})
			return
		}

		c.JSON(http.StatusOK, RegisterRes{Data: req})
	})
	r.Run()
}

访问http://localhost:8080/register?name=john&password1=pwd1&password2=pwd2,可得到{"code":0,"error":"","data":{"Name":"","Pass":"pwd1","Pass2":"pwd2"}}

展示的案例是绑定get请求的query参数,其他的情况可参考

只绑定Get参数 官方
只绑定Get参数 中文
绑定Get参数或者Post参数 官方
绑定Get参数或者Post参数 中文
绑定uri 官方
绑定uri 中文
绑定HTML复选框 官方
绑定HTML复选框 中文
绑定Post参数 官方
绑定Post参数 中文
表单数据解析和绑定
URI数据解析和绑定

JSON/XML

从GoFrame v1.11版本开始,Request对象提供了对客户端提交的JSON/XML数据格式的原生支持。可通过 Parse 方法转换json或xml

具体案例可参考 GoFrame 请求输入JSON/XML转换

gin也类似,gin提供 Must bind 和 Should bind 两种绑定方法,具体使用时根据 json,xml,yaml等使用不同的函数。两种绑定方法的区别在于当存在绑定错误时是否直接终止请求亦或者交由开发人员处理。

具体案例可参考
模型绑定和验证 官方
模型绑定和验证 中文
Json 数据解析和绑定

请求校验

goframe 和 gin 的校验方式形式上差不多,都支持自定义的校验模式,不同的是,goframe还支持将错误转换为错误接口,这样可以控制不一次性输出全部错误,一次性输出全部错误有时候对用户并不友好。诸如每次只输出第一个校验错误。

goframe 请求校验示例
gin 自定义校验示例
gin 结构体验证
gin 自定义验证

默认值绑定

goframe 和 gin 都支持默认值绑定,uri,query,form等都是支持默认值的。默认值绑定的一个常用场景是,列表分页时的每页默认条数和当前页数的赋值。

goframe 默认值绑定 示例

goframe支持json的默认值绑定,而gin并不能直接在结构体定义的时候设置默认值,可行的方法在实例化json时再自行设置默认值。gin官方文档中并没详细如何处理参数的默认值问题,所以我下面写个示例补充一下。

gin的uri,form等默认取值比较简单,使用 DefaultQuery 和 DefaultPostForm 即可解决默认值的问题

	route.GET("/", func(c *gin.Context) {
		c.DefaultQuery("name", "john")
	})

或者,也可以在定义结构体的时候声明

type ListInfo struct {
	Page int `form:"page,default=1" json:"page" xml:"page" `
	Size int `form:"size,default=10" json:"size" xml:"size" `
}

gin设定 json 与 xml 的默认值

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// Binding from JSON
type ListInfo struct {
	Page int `form:"page,default=1" json:"page" xml:"page" `
	Size int `form:"size,default=10" json:"size" xml:"size" `
}

func main() {
	router := gin.Default()

	// Example for binding JSON ({"user": "manu", "password": "123"})
	router.POST("/listJSON", func(c *gin.Context) {
		json := ListInfo{
			Page: 1,
			Size: 10,
		}
		if err := c.ShouldBindJSON(&json); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		c.JSON(http.StatusOK, json)
	})

	// Example for binding XML (
	//	<?xml version="1.0" encoding="UTF-8"?>
	//	<root>
	//		<page>1</page>
	//		<size>10</size>
	//	</root>)
	router.POST("/listXML", func(c *gin.Context) {
		xml := ListInfo{
			Page: 1,
			Size: 10,
		}
		if err := c.ShouldBindXML(&xml); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		c.JSON(http.StatusOK, xml)
	})

	// Listen and serve on 0.0.0.0:8080
	router.Run(":8080")
}

自定义变量 与 Context

开发者可以在请求中自定义一些变量设置, goframe 和 gin 都支持。

goframe文档 自定义变量
goframe文档 Context
gin中间件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值