🏆 HttpRouter

⭐️ Gin的路由组件采用的是 HttpRouter,它同样也是一个轻量级、高性能的路由组件,它整个组件只有3个 go文件

⭐️ HttpRouter特点:

1.一对一匹配:一个请求只能匹配到零个或一个路由,且有利于SEO优化。

2.路径自动校正:随意选择喜欢的URL风格,就算多了或者少了一个斜杠,也会自动重定向。如果有大小写错误的话,查找时也会忽略大小写进行正确的重定向。

3.路由参数自动解析:只要给路径段一个名称,路由器就会把动态值传递给你。由于路由器的设计,路径参数解析的占用非常低廉。

4.零垃圾:在路由分配与调度的过程中,不会产生任何内存垃圾。

5.RefstfulAPI支持:路由器的设计鼓励合理的分层的Restful API。

6.错误处理:可以设置一个错误处理器来处理请求中的异常,路由器会将其捕获并记录,然后重定向到错误页面。

🌟 基本用法

⭐️ 和 SpringBoot一样,一个方法函数,对应着处理一个 URL

⭐️ 看起来和原生 http包中使用差不多,但是路由处理器换成的了 HttpRouter

⭐️ Fprintf用于格式化输出数据到一个 io.Writer接口,w表示要写入数据的目标,它必须实现了 io.Writer 接口。在 Web 开发的上下文中,w 通常是一个响应写入器(ResponseWriter),用于向客户端发送 HTTP 响应,后面则是要写入的数据

package main

import (
   "fmt"
   "github.com/julienschmidt/httprouter"
   "log"
   "net/http"
)

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
   fmt.Fprintf(w, "<h1>Hello World!")
}

func main() {
   router := httprouter.New()
   router.GET("/hello:name", Hello)
   log.Fatal(http.ListenAndServe(":8080", router))
}

⭐️ 我使用的是 goland,在 goland中运行,在浏览器中访问

image-20240619221723712

🌟 提供的方法

⭐️ 就是将 http包在封装了一下

func (r *Router) GET(path string, handle Handle) {
	r.Handle(http.MethodGet, path, handle)
}

func (r *Router) HEAD(path string, handle Handle) {
	r.Handle(http.MethodHead, path, handle)
}

func (r *Router) OPTIONS(path string, handle Handle) {
	r.Handle(http.MethodOptions, path, handle)
}

// POST is a shortcut for router.Handle(http.MethodPost, path, handle)
func (r *Router) POST(path string, handle Handle) {
	r.Handle(http.MethodPost, path, handle)
}

func (r *Router) PUT(path string, handle Handle) {
	r.Handle(http.MethodPut, path, handle)
}

func (r *Router) PATCH(path string, handle Handle) {
	r.Handle(http.MethodPatch, path, handle)
}

func (r *Router) DELETE(path string, handle Handle) {
	r.Handle(http.MethodDelete, path, handle)
}

🌟命名参数(路径匹配规则)

⭐️ 它有两种路径匹配规则:

  1. :name 更具路由命捕获,获方式是匹配内容直到下一个斜线或者路径的结尾
  2. *name 表示捕获任意内容

1️⃣ :name

⭐️ 使用 httprouter.Params可以直接获取到路径匹配

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}

func main() {
	router := httprouter.New()
	router.GET("/", Index)
	router.GET("/hello/:name", Hello)

	log.Fatal(http.ListenAndServe(":8080", router))
}

打开浏览器访问

image-20240620001717750

🌟 自动添加请求头

⭐️ 先判断请求头某个字段是否不存在,不存在则添加山上,下面这个多用于跨域

router.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.Header.Get("Access-Control-Request-Method") != "" {
        // 设置CORS标头
        header := w.Header()
        header.Set("Access-Control-Allow-Methods", header.Get("Allow"))
        header.Set("Access-Control-Allow-Origin", "*")
    }

    // 调整状态码为204
    w.WriteHeader(http.StatusNoContent)
})