Gin自定义服务器配置与路由参数获取

417 阅读5分钟

自定义HTTP服务器的配置

func main() {
	// 得到一个默认的Gin路由器实例
	router := gin.Default()

	s := &http.Server{
		// Addr:指定服务器监听的地址和端口号
		Addr: ":8080",
		// Handler:指定处理HTTP请求的路由器为router
		Handler: router,
		// ReadTimeout:指定服务器读取请求的超时时间
		ReadTimeout: time.Second * 10,
		// WriteTimeout:指定服务器写出响应的超时时间
		WriteTimeout: time.Second * 10,
		// MaxHeaderBytes:指定请求头的最大字节数
		MaxHeaderBytes: 1 << 20,
	}
	// 通过s.ListenAndServe方法启动服务器,开始监听指定的地址和端口号,并处理传入的HTTP请求
	s.ListenAndServe()
}

这段代码的作用是启动一个HTTP服务器,使用Gin框架处理HTTP请求,并监听在本地的8080端口上

路由

// 创建带有默认中间件的路由:
// 日志与恢复中间件
router := gin.Default()
//创建不带中间件的路由:
//r := gin.New()

router.GET("/someGet", getting)
router.POST("/somePost", posting)
router.PUT("/somePut", putting)
router.DELETE("/someDelete", deleting)
router.PATCH("/somePatch", patching)
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)解释一下这些代码

首先,通过gin.Default()函数创建一个带有默认中间件的路由。默认中间件包括日志中间件和恢复中间件,用于记录请求日志和处理恢复。

然后,使用router.GET()router.POST()等方法定义不同HTTP方法的路由。每个方法接受两个参数,第一个参数是路由的路径,第二个参数是处理该路由的处理函数。

例如,router.GET("/someGet", getting)表示当收到GET请求并且路径为"/someGet"时,将调用名为getting的处理函数来处理该请求。

最后,通过router.Run()方法启动路由,监听指定的端口并开始接收HTTP请求。

当然,其他请求也是类似的

这里给出一个例子,简单解释一下代码的意思

func main() {
	// 给出一个带有默认中间件的路由
	// 默认中间件内包含日志和恢复中间件
	router := gin.Default()
	router.GET("/helloWorld", func(ctx *gin.Context) {
		fmt.Println("helloWorld")
	})
	router.Run()
}

这里,我们访问默认的路由,因为我们设置了GET请求,所以直接访问了下面这个地址

http://localhost:8080/helloWorld

图片.png 这里发现默认路由监听了我们的端口,并打印了日志,说明方法有效

路由参数

gin的路由来自httprouter库。因此httprouter具有的功能,gin也具有,不过gin不支持路由正则表达式。

参数通过ContextParam方法来获取。

直接给出示例更好理解

func main() {
	// 给出一个带有默认中间件的路由
	// 默认中间件内包含日志和恢复中间件
	router := gin.Default()
	router.GET("/helloWorld/:name", func(ctx *gin.Context) {
		name := ctx.Param("name")
		fmt.Println("helloWorld" + name)
	})
	router.Run()
}

这里还是一个带有默认中间件的路由,路由发送了一个GET请求,地址为/helloWorld/:name

当然:name是一个参数,你可以写任意,这个的返回值是个string

通过Context对象来获取对应的参数

我们来测试一下,访问http://localhost:8080/helloWorld/666

此时控制台打印:

图片.png 冒号:加上一个参数名组成路由参数。可以使用c.Params的方法读取其值。当然这个值是字串string。诸如/helloWorld/hanru,和/helloWorld/hello都可以匹配,而/helloWorld//user/hanru/不会被匹配。

router.GET("/user/:name/*action", func(c *gin.Context) {
    name := c.Param("name")
    action := c.Param("action")
    message := name + " is " + action
    c.String(http.StatusOK, message)
})

浏览器中输入http://127.0.0.1:8000/user/hanru/send

除了:,gin还提供了*号处理参数,*号能匹配的规则就更多。

在gin中,*号用于处理参数,可以匹配多个路径段或者参数。下面是一些常见的使用情况:

  1. 匹配多个路径段: 当在路由中使用星号时,它可以匹配多个路径段。例如,如果我们有一个路由路径为/users/*action,那么它将匹配所有以/users/开头的路径,并且*号将匹配剩余的路径段。

  2. 例如,/users/create/users/update/users/delete等路径都会被匹配到,并且*action将捕获到createupdatedelete等值。

  3. 匹配多个参数: 当在路由中的参数使用号时,它可以匹配多个参数。例如,如果我们有一个路由路径为/users/:name/*action,那么它将匹配所有以/users/开头的路径,并且:name参数将匹配到路径中的第一个参数,而action参数将匹配到剩余的参数。例如,/users/john/create/users/john/update/users/john/delete等路径都会被匹配到,并且:name参数将捕获到john值,*action参数将捕获到createupdatedelete等值。

需要注意的是,星号只能匹配到路径中的一个片段或者参数,不能匹配到多级的路径。例如,/users/*/create是无效的,因为*号只能匹配一个路径段或者参数。

当然,有时候获取参数可能会出现URL参数的情况,就是?key1=value1&key2=value2这样的类似的

URL 参数通过 DefaultQueryQuery 方法获取。

对于参数的处理,经常会出现参数不存在的情况,对于是否提供默认值,gin也考虑了,并且给出了一个优雅的方案,使用c.DefaultQuery方法读取参数,其中当参数不存在的时候,提供一个默认值。使用Query方法读取正常参数,当参数不存在的时候,返回空字串。

func main() {
	router := gin.Default()
	router.GET("/helloworld", func(ctx *gin.Context) {
		// 访问name这个字段值,没有的话就给出默认值9527
		name := ctx.DefaultQuery("name", "9527")
        // 访问age这个字段值,没有的话就给出默认空字符串
		age := ctx.Query("age")
		ctx.String(http.StatusOK, fmt.Sprint("hello my name is ", name, "age:", age))
	})
	router.Run(":9527")
}

图片.png

这里端口别写错了哈

http的报文体传输数据就比query string稍微复杂一点,常见的格式就有四种。例如application/jsonapplication/x-www-form-urlencoded,application/xmlmultipart/form-data。后面一个主要用于图片上传。json格式的很好理解,url其实也不难,无非就是把query string的内容,放到了body体里,同样也需要urlencode。默认情况下,c.PostFROM解析的是x-www-form-urlencodedfrom-data的参数。

表单参数通过 PostForm 方法获取:

func main() {
	router := gin.Default()
	router.POST("/form", func(ctx *gin.Context) {
		type1 := ctx.DefaultPostForm("type", "typeDefault")
		username := ctx.PostForm("username")
		password := ctx.PostForm("password")
		ctx.String(http.StatusOK, fmt.Sprintln("type:", type1, "username:", username, "password:", password))
	})
	router.Run()
}

图片.png