您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。