go常用包快速上手: net/http快速掌握

60 阅读2分钟

go常用包快速上手: net/http快速掌握

net/http是Go语言的标准库之一,为HTTP客户端和服务端提供了强大而灵活的支持。以下是该包的核心要点、基本用法。

一、net/http包概览

net/http包是Go标准库的一部分,它实现了HTTP客户端和服务端的所有基本功能。这个包提供了处理HTTP请求和响应的接口,包括监听HTTP端口、解析请求、发送响应等。通过net/http,你可以轻松实现RESTful API、Web服务器、反向代理等多种HTTP应用。

二、基本用法

2.1 编写一个简单的HTTP服务器

下面是一个使用net/http包编写的简单HTTP服务器示例,它监听本地的8080端口,并对所有请求返回"Hello, World!"。

package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, World!")
}

func main() {
	http.HandleFunc("/", helloHandler)
	engin := http.DefaultServeMux // 借用默认服务
	fmt.Println("Server is listening on http://localhost:8080")
	// 服务端初始化
	server := http.Server{
		Addr:    ":8080",
		Handler: engin,
	}
	// 创建系统信号接收器
	// 优雅关闭
	done := make(chan os.Signal)
	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		<-done
		if err := server.Shutdown(context.Background()); err != nil {
			log.Fatal("Shutdown server:", err)
		}
	}()
	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}
}

2.2 自定义路由

虽然http.HandleFunc可以处理简单的路由需求,但在实际应用中,我们往往需要更灵活的路由控制。这时,可以使用第三方库如gorilla/mux来实现更复杂的路由逻辑。不过,为了保持示例的简洁性,这里仅展示net/http的基本用法。

三、进阶技巧

3.1 中间件的使用

虽然net/http本身不直接支持中间件的概念,但我们可以通过封装http.Handler接口来实现类似的功能。中间件允许你在请求处理流程中插入额外的逻辑,如日志记录、身份验证、请求限流等。

type middlewareFunc func(http.Handler) http.Handler

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("Request URL:", r.URL.Path)
        next.ServeHTTP(w, r)
    })
}

func main() {
    handler := loggingMiddleware(http.HandlerFunc(helloHandler))
    http.ListenAndServe(":8080", handler)
}

3.2 并发处理

Go的goroutine和channel机制使得并发处理HTTP请求变得异常简单。net/http包内部已经为我们处理了大部分并发细节,但了解这一点对于编写高效的服务至关重要。

3.3 自定义HTTP客户端

除了服务端,net/http还提供了强大的HTTP客户端功能。通过自定义http.Client,你可以控制超时时间、重定向策略、Cookie处理等。

GET

client := &http.Client{
    Timeout: time.Second * 10, // 设置超时时间为10秒
}

resp, err := client.Get("http://example.com")
if err != nil {
    // 处理错误
}
defer resp.Body.Close()
// 处理响应...

POST

package main  
  
import (  
    "bytes"  
    "fmt"  
    "io/ioutil"  
    "net/http"  
)  
  
func main() {  
    // 设置POST数据  
    data := []byte(`{"key":"value"}`)  
    req, err := http.NewRequest("POST", "http://example.com/api", bytes.NewBuffer(data))  
    if err != nil {  
        panic(err)  
    }  
  
    // 设置请求头  
    req.Header.Set("Content-Type", "application/json")  
  
    // 发起请求  
    client := &http.Client{}  
    resp, err := client.Do(req)  
    if err != nil {  
        panic(err)  
    }  
    defer resp.Body.Close()  
  
    // 读取响应体  
    body, err := ioutil.ReadAll(resp.Body)  
    if err != nil {  
        panic(err)  
    }  
    fmt.Println(string(body))  
}

后记

这些就是net/http基本用法。