Go语言net/http包的实战小结
作者:有浔则灵
本文主要介绍了Go语言net/http包的实战,包括HTTP服务端搭建、请求处理、路由匹配、参数获取等内容,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Go 语言的标准库 net/http 提供了强大的 HTTP 客户端和服务端实现,是构建 Web 应用和 API 的基础。本文将从零开始,带你全面掌握 net/http 包的使用,包括服务端搭建、请求处理、路由匹配、参数获取、最佳实践等内容,并重点介绍 Go 1.22 带来的路由增强特性。
一、HTTP 服务端基础
1.1 最简单的 HTTP 服务器
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
http.ListenAndServe(":8080", nil)
}
1.2 核心接口:http.Handler
任何实现了 ServeHTTP(ResponseWriter, *Request) 方法的类型都可以作为 HTTP 处理器。
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
1.3 服务启动的两种方式
✅ 使用默认路由(包级别函数)
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
✅ 自定义 Server 实例(推荐生产环境)
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
1.4 支持 HTTPS
http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
二、请求与响应处理
2.1 核心对象
- http.ResponseWriter:构造响应
- *http.Request:获取请求信息
2.2 构建响应示例
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"status": "success"}`))
}
2.3 读取请求信息
method := r.Method
path := r.URL.Path
userAgent := r.Header.Get("User-Agent")
ip := r.RemoteAddr
三、路由与路径匹配
3.1 基础路由注册
http.HandleFunc("/", homeHandler)
http.HandleFunc("/users", usersHandler)
3.2 自定义 ServeMux
mux := http.NewServeMux()
mux.HandleFunc("/", homeHandler)
http.ListenAndServe(":8080", mux)
3.3 Go 1.22+ 路由增强
✅ 方法匹配
http.HandleFunc("GET /posts/{id}", handleGetPost)
http.HandleFunc("POST /posts", handleCreatePost)
✅ 路径通配符
http.HandleFunc("GET /posts/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
fmt.Fprintf(w, "Post ID: %s", id)
})
✅ 剩余路径匹配
http.HandleFunc("GET /files/{path...}", func(w http.ResponseWriter, r *http.Request) {
path := r.PathValue("path")
fmt.Fprintf(w, "File path: %s", path)
})
3.4 路由优先级规则
- 最具体模式获胜(Go 1.22+)
- 传统规则:长路径优先
四、请求方法处理
4.1 方法判断
switch r.Method {
case http.MethodGet:
handleGet(w, r)
case http.MethodPost:
handlePost(w, r)
}
4.2 Go 1.22+ 方法限定
mux.HandleFunc("GET /users", listUsers)
mux.HandleFunc("POST /users", createUser)
4.3 第三方路由库(gorilla/mux)
r := mux.NewRouter()
r.HandleFunc("/products/{id:[0-9]+}", productHandler)
五、请求参数处理
| 参数类型 | 获取方式 | 示例 |
|---|---|---|
| 查询参数 | r.URL.Query().Get("key") | /users?page=1 |
| 表单参数 | r.FormValue("key") | username=john |
| 路径参数 | r.PathValue("id") | /users/123 |
| JSON 请求体 | json.NewDecoder(r.Body).Decode | {"name":"john"} |
| 原始请求体 | io.ReadAll(r.Body) | 二进制 / XML 等 |
JSON 解析示例
var user User err := json.NewDecoder(r.Body).Decode(&user)
六、完整示例:RESTful API(Go 1.22+)
package main
import (
"encoding/json"
"net/http"
"strconv"
"sync"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
var (
users = make(map[int]User)
nextID = 1
usersMu sync.RWMutex
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /users", listUsers)
mux.HandleFunc("POST /users", createUser)
mux.HandleFunc("GET /users/{id}", getUser)
mux.HandleFunc("PUT /users/{id}", updateUser)
mux.HandleFunc("DELETE /users/{id}", deleteUser)
http.ListenAndServe(":8080", mux)
}
// 各函数实现略(详见原文)
七、常见错误与最佳实践
❌ 常见错误
- 未关闭响应体
- 在写入响应体后调用
WriteHeader - 忽略错误处理
- 未设置超时
✅ 最佳实践
- 重用 HTTP 客户端
- 使用 Context 控制超时
- 统一响应格式
- 输入验证
- 优雅关闭服务器
优雅关闭示例
srv := &http.Server{Addr: ":8080", Handler: mux}
go srv.ListenAndServe()
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)
八、总结
| 组件 | 关键类型/函数 | 用途 |
|---|---|---|
| 服务端 | http.ListenAndServe、http.Server | 启动服务 |
| 处理器 | Handler 接口、HandleFunc | 处理请求 |
| 请求 | *http.Request | 获取请求信息 |
| 响应 | http.ResponseWriter | 构建响应 |
| 路由 | ServeMux、DefaultServeMux | 路由分发 |
| 参数 | URL.Query()、FormValue()、PathValue() | 获取请求参数 |
Go 1.22+ 亮点
- 方法匹配
- 路径通配符
- 最具体规则
学习建议
- 从标准库入手,理解
Handler接口 - 注意 Go 版本差异(1.22 路由增强)
- 实践时注重错误处理、超时控制、资源关闭
到此这篇关于Go语言net/http包的实战小结的文章就介绍到这了,更多相关Go语言net/http包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
