在路由之前,如何获取URL?

huangapple go评论87阅读模式
英文:

How do I get the URL before routing?

问题

我想在路由之前获取路由的URL或名称,例如:

router.HandleFunc("/person", person.HandlePerson)
router.HandleFunc("/animal", animal.HandleAnimal)

我想在路由之前像这样知道路由的名称:

nameOfRoute := //我想让这个变量存储路由的名称(person或animal)
fmt.Println(nameOfRoute) //这行代码将打印路由的名称("/animal"或"/person")
router.HandleFunc("/person", person.HandlePerson)
router.HandleFunc("/animal", animal.HandleAnimal)

在Golang中,你可以通过使用http.HandlerFunc类型的函数来实现这一点。你可以创建一个自定义的HandlerFunc函数,它会在路由之前打印路由的名称,并将其存储在变量中。以下是一个示例代码:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	router := http.NewServeMux()
	router.HandleFunc("/person", logAndHandle(person.HandlePerson, "/person"))
	router.HandleFunc("/animal", logAndHandle(animal.HandleAnimal, "/animal"))

	// 启动服务器
	http.ListenAndServe(":8080", router)
}

func logAndHandle(handler http.HandlerFunc, routeName string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Println(routeName)
		handler(w, r)
	}
}

func HandlePerson(w http.ResponseWriter, r *http.Request) {
	// 处理/person路由的逻辑
}

func HandleAnimal(w http.ResponseWriter, r *http.Request) {
	// 处理/animal路由的逻辑
}

在上面的示例中,我们创建了一个名为logAndHandle的辅助函数,它接受一个HandlerFunc和路由名称作为参数。该函数会在路由之前打印路由的名称,并调用原始的HandlerFunc来处理请求。你可以根据需要修改logAndHandle函数的实现来满足你的需求。

英文:

I want to get the url or the neme of the route before routing it, ex:

router.HandleFunc("/person", person.HandlePerson)
router.HandleFunc("/animal", animal.HandleAnimal)

I want to know the route before routing like this:

nameOfRoute:=    //I want this variable to store the name of the route (person or animal) before routing 
fmt.Println(nameOfRoute) //This line will print the name of the route ("/animal", "/person")
router.HandleFunc("/person", person.HandlePerson)
router.HandleFunc("/animal", animal.HandleAnimal)

How can I do this in Golang

答案1

得分: 1

你不能以你展示的方式进行路由。那是因为这些语句

router.HandleFunc("/person", person.HandlePerson)

不是实际进行路由的操作,而是指示路由器如何进行路由的指令。
路由本身是通过路由器的一个“入口”函数来处理的。

然而,你可以使用多个路由器进行“级联”:

  1. 创建一个处理/的路由器,然后创建另一个处理所有个别路由的路由器 - 就像目前所做的那样。
  2. 让第一个 - 根 - 路由器的唯一处理函数打印URL,然后仅调用内部路由器的入口函数。
    我不知道你使用的是哪个路由器包(有很多,包括默认的),所以我不能告诉你那个函数是什么;在默认的路由器中,它是ServeHTTP
    请考虑将此作为作业来解决 在路由之前,如何获取URL?

使用默认的net/httpServeMux,你甚至不需要一个根路由器,因为一个函数就足够了 - 就像这样:

mux := http.NewServeMux()
mux.Handle("/person", whatever)
...

server := http.Server{
  Handler: func(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.URL)
    mux.ServeHTTP(w, r)
  },
}

server.ListenAndServe()
英文:

You cannot — in the sense that you showed. That's because the statements

router.HandleFunc("/person", person.HandlePerson)

are not actions which carry out actual routing but rather directives to the router about how it should do routing.
The routing itself is handler via a single "entry" function of your router.

What you can do, however, is to employ "cascading" of several routers:

  1. Create a router which handles /, and then create another router which handles all your indiviual routes — as it's currently done.
  2. Make the sole handler function of the first — root — router print the URL and then merely call the inner's router entry function.
    I have no idea which router package are you using (there are gazillions of them, including the stock one) so I cannot tell you what that function is; in a stock router it's ServeHTTP.
    Please consider figuring this out as a homework 在路由之前,如何获取URL?

With a stock net/http's ServeMux, you do not even need a root router because a single function would do — something like this:


mux := http.NewServeMux()
mux.Handle("/person", whatever)
...

server := http.Server{
  Handler: func(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.URL)
    mux.ServeHTTP(w, r)
  },
}

server.ListenAndServe()

huangapple
  • 本文由 发表于 2021年12月7日 01:57:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/70249815.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定