您好,登录后才能下订单哦!
密码登录
            
            
            
            
        登录注册
            
            
            
        点击 登录注册 即表示同意《亿速云用户服务条款》
        # Golang中如何使用 net/http 库
## 引言
Go语言(Golang)以其简洁的语法、高效的并发模型和强大的标准库而闻名。在标准库中,`net/http`包是构建HTTP客户端和服务器的核心工具。本文将深入探讨如何使用`net/http`库,涵盖从基础到进阶的各个方面。
## 1. net/http库概述
`net/http`是Go标准库中用于处理HTTP协议的包,它提供了:
- HTTP客户端实现
- HTTP服务端实现
- URL解析
- Cookie管理
- 文件上传处理
- 连接复用等高级特性
### 1.1 主要组件
```go
// 客户端相关
type Client struct{...}
func (c *Client) Do(req *Request) (*Response, error)
// 服务端相关
type Server struct{...}
func ListenAndServe(addr string, handler Handler) error
package main
import (
    "fmt"
    "net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}
func main() {
    http.HandleFunc("/hello", helloHandler)
    fmt.Println("Server starting on port 8080...")
    http.ListenAndServe(":8080", nil)
}
func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/hello", helloHandler)
    mux.HandleFunc("/about", aboutHandler)
    
    server := &http.Server{
        Addr:    ":8080",
        Handler: mux,
    }
    
    log.Fatal(server.ListenAndServe())
}
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("Request: %s %s", r.Method, r.URL.Path)
        next.ServeHTTP(w, r)
    })
}
func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", homeHandler)
    
    wrappedMux := loggingMiddleware(mux)
    
    http.ListenAndServe(":8080", wrappedMux)
}
func userHandler(w http.ResponseWriter, r *http.Request) {
    // 获取查询参数
    name := r.URL.Query().Get("name")
    
    // 读取POST表单数据
    err := r.ParseForm()
    if err != nil {
        http.Error(w, "Bad Request", http.StatusBadRequest)
        return
    }
    email := r.Form.Get("email")
    
    // 读取JSON请求体
    var user User
    if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        // 处理GET请求
    case http.MethodPost:
        // 处理POST请求
    case http.MethodPut:
        // 处理PUT请求
    default:
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
    }
}
func jsonHandler(w http.ResponseWriter, r *http.Request) {
    data := map[string]interface{}{
        "status":  "success",
        "message": "Hello, JSON!",
    }
    
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(data)
}
func fileHandler(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "./static/image.png")
}
// 或者使用FileServer
func main() {
    fs := http.FileServer(http.Dir("./static"))
    http.Handle("/static/", http.StripPrefix("/static/", fs))
}
func fetchData() {
    resp, err := http.Get("https://api.example.com/data")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(string(body))
}
func customClient() {
    client := &http.Client{
        Timeout: 10 * time.Second,
        Transport: &http.Transport{
            MaxIdleConns:        10,
            IdleConnTimeout:    30 * time.Second,
            DisableCompression: true,
        },
    }
    
    req, err := http.NewRequest("GET", "https://api.example.com", nil)
    if err != nil {
        log.Fatal(err)
    }
    
    req.Header.Add("Authorization", "Bearer token123")
    
    resp, err := client.Do(req)
    // 处理响应...
}
func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Secure connection!"))
    })
    
    err := http.ListenAndServeTLS(
        ":443",
        "server.crt",
        "server.key",
        mux,
    )
    if err != nil {
        log.Fatal(err)
    }
}
func insecureClient() {
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
    
    resp, err := client.Get("https://self-signed.example.com")
    // 处理响应...
}
func pooledClient() {
    client := &http.Client{
        Transport: &http.Transport{
            MaxIdleConns:        100,
            MaxIdleConnsPerHost: 10,
            IdleConnTimeout:    90 * time.Second,
        },
        Timeout: 10 * time.Second,
    }
    
    // 复用client进行多次请求
}
func timeoutExample() {
    // 服务端设置超时
    server := &http.Server{
        Addr:         ":8080",
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
    }
    
    // 客户端设置超时
    client := &http.Client{Timeout: 5 * time.Second}
}
func gracefulShutdown() {
    server := &http.Server{Addr: ":8080"}
    
    go func() {
        if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Fatalf("listen: %s\n", err)
        }
    }()
    
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt)
    <-quit
    
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    if err := server.Shutdown(ctx); err != nil {
        log.Fatal("Server forced to shutdown:", err)
    }
}
var client = &http.Client{
    Transport: &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 10,
        IdleConnTimeout:    30 * time.Second,
    },
    Timeout: 10 * time.Second,
}
问题:未关闭响应体
resp, err := http.Get(url)
// 错误:缺少 defer resp.Body.Close()
解决方案:
defer resp.Body.Close()
问题:未限制并发连接数
解决方案:
transport := &http.Transport{
    MaxIdleConns:        100,
    MaxConnsPerHost:    10,
}
解决方案:
client := &http.Client{
    Timeout: 5 * time.Second,
}
type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}
func usersHandler(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        // 获取用户列表
        users := []User{...}
        json.NewEncoder(w).Encode(users)
    case http.MethodPost:
        // 创建新用户
        var user User
        json.NewDecoder(r.Body).Decode(&user)
        // 保存用户...
        w.WriteHeader(http.StatusCreated)
    }
}
func uploadHandler(w http.ResponseWriter, r *http.Request) {
    // 限制上传大小
    r.ParseMultipartForm(10 << 20) // 10MB
    
    file, handler, err := r.FormFile("file")
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    defer file.Close()
    
    // 保存文件
    dst, err := os.Create(handler.Filename)
    // ...处理错误
    defer dst.Close()
    
    io.Copy(dst, file)
    fmt.Fprintf(w, "Upload successful")
}
Go的net/http包提供了强大而灵活的工具来构建HTTP客户端和服务端应用。通过本文的介绍,您应该已经掌握了:
无论是构建简单的Web服务还是复杂的分布式系统,net/http都能提供坚实的基础。随着Go语言的不断发展,这个标准库也在持续改进,值得开发者深入学习和掌握。
希望本文能帮助您更好地理解和使用Go语言的net/http库!
“`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。