Golang中Handler函数的返回处理

Golang中Handler函数的返回处理 我有一个处理函数:http.HandleFunc("/welcome", ValidateToken(Welcome))

func ValidateToken(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
next.Serv(w,r)
}}
func Welcome(w http.ResponseWriter, r *http.Request) {
fmt.Println("welcoma page")
w.Write([]byte("sads"))
}

如何从ValidateToken返回某些内容,以便能够在Welcome函数中使用它? 我在ValidateToken中进行验证,然后这些信息也需要在Welcome函数中使用。

谢谢。


更多关于Golang中Handler函数的返回处理的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你可以使用全局变量,或者也可以使用接收器… 另一个选择是使用 context 包。

更多关于Golang中Handler函数的返回处理的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


miha: http.HandleFunc("/welcome", ValidateToken(Welcome))

请查看Go语言中闭包的5种实用方法。特别是第3种用法。

package main

import (
  "fmt"
  "net/http"
)

type Database struct {
  Url string
}

func NewDatabase(url string) Database {
  return Database{url}
}

func main() {
  db := NewDatabase("localhost:5432")

  http.HandleFunc("/hello", hello(db))
  http.ListenAndServe(":3000", nil)
}

func hello(db Database) func(http.ResponseWriter, *http.Request) {
  return func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, db.Url)
  }
}

在Go的HTTP中间件模式中,你可以通过向请求的上下文(Context)添加值来在中间件和处理函数之间传递数据。以下是修改后的代码示例:

func ValidateToken(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 模拟验证逻辑
        userID := "12345"
        isValid := true
        
        // 将验证结果添加到请求上下文
        ctx := context.WithValue(r.Context(), "userID", userID)
        ctx = context.WithValue(ctx, "isValid", isValid)
        
        // 使用新的上下文继续处理
        next.ServeHTTP(w, r.WithContext(ctx))
    }
}

func Welcome(w http.ResponseWriter, r *http.Request) {
    // 从上下文中获取验证信息
    userID := r.Context().Value("userID").(string)
    isValid := r.Context().Value("isValid").(bool)
    
    fmt.Printf("UserID: %s, Valid: %t\n", userID, isValid)
    w.Write([]byte("Welcome page - User: " + userID))
}

如果你需要传递更复杂的数据结构,可以定义一个自定义类型:

type contextKey string

const (
    userKey contextKey = "user"
)

type UserInfo struct {
    ID    string
    Name  string
    Email string
}

func ValidateToken(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 模拟用户验证
        userInfo := UserInfo{
            ID:    "12345",
            Name:  "John Doe",
            Email: "john@example.com",
        }
        
        // 使用类型安全的上下文键
        ctx := context.WithValue(r.Context(), userKey, userInfo)
        next.ServeHTTP(w, r.WithContext(ctx))
    }
}

func Welcome(w http.ResponseWriter, r *http.Request) {
    // 从上下文中获取用户信息
    userInfo := r.Context().Value(userKey).(UserInfo)
    
    fmt.Printf("Welcome %s (ID: %s)\n", userInfo.Name, userInfo.ID)
    w.Write([]byte(fmt.Sprintf("Welcome %s!", userInfo.Name)))
}

这种方式确保了验证信息在中间件和处理函数之间的安全传递,同时保持了代码的清晰性和类型安全性。

回到顶部