如何覆盖Go net/http默认的404未找到请求处理器?
如何自定义Go http.ServeMux的404响应
你用"*"作为路由注册自定义404处理器不生效,核心原因是Go的http.ServeMux路由匹配规则里,通配符*只能作为路径前缀的尾部(比如/api/*),单独的*不会匹配任何请求路径,所以这个处理器永远不会被触发。
下面是两种可行的解决方法:
方法一:包装ServeMux实现自定义404
创建一个自定义Handler类型,包装原有的ServeMux,通过捕获响应状态码来判断是否需要返回自定义404:
package main import ( "net/http" ) type customMux struct { mux *http.ServeMux } func (c *customMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 用自定义ResponseRecorder捕获原ServeMux的响应状态 rec := &responseRecorder{ResponseWriter: w, statusCode: http.StatusOK} c.mux.ServeHTTP(rec, r) // 如果原响应是404,替换为自定义内容 if rec.statusCode == http.StatusNotFound { w.WriteHeader(http.StatusNotFound) w.Write([]byte("自定义404错误:请求的路径不存在")) } } // 自定义ResponseRecorder,用于捕获响应状态码 type responseRecorder struct { http.ResponseWriter statusCode int } func (r *responseRecorder) WriteHeader(code int) { r.statusCode = code r.ResponseWriter.WriteHeader(code) } func main() { api := http.NewServeMux() api.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("test success")) }) // 使用自定义的mux替代原ServeMux customHandler := &customMux{mux: api} err := http.ListenAndServe(":8080", customHandler) if err != nil { panic(err) } }
方法二:利用最长匹配规则注册根路径处理器
http.ServeMux遵循最长路径匹配原则,注册一个"/"的处理器,只有当所有更具体的路径都不匹配时,才会触发这个根处理器,直接返回自定义404:
package main import "net/http" func main() { api := http.NewServeMux() api.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("test success")) }) // 注册根路径处理器,仅在无其他匹配时触发 api.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 可选:排除favicon.ico请求,避免不必要的404日志 if r.URL.Path == "/favicon.ico" { http.NotFound(w, r) return } w.WriteHeader(http.StatusNotFound) w.Write([]byte("自定义404错误:请求的路径不存在")) }) err := http.ListenAndServe(":8080", api) if err != nil { panic(err) } }
内容的提问来源于stack exchange,提问作者baitendbidz
相关产品推荐
相关产品推荐

