【魅力golang】之——内置包net/http使用指南
net/http 是Go 语言标准库中的一个重要包,用于处理 HTTP 请求和响应,支持客户端和服务器功能。它提供了简洁高效的接口来处理常见的 HTTP 协议操作,包括请求的发送、响应的接收、HTTP 服务器的搭建等。对于 Web 开发、API 接口调用、以及构建 HTTP 服务,net/http 是非常常用的工具。
1、net/http 包概述
net/http 包提供了丰富的功能,包括:
·HTTP 客户端:发送HTTP 请求,处理响应。
·HTTP 服务器:处理客户端的HTTP 请求,生成并返回响应。
·路由和处理器:通过多种方式处理不同类型的HTTP 请求。
·中间件支持:通过处理器链实现请求预处理和后处理。
2、 安装和导入
Go 语言的net/http 包是标准库的一部分,无需安装,只需直接导入即可使用:
import "net/http"
3、 作为 HTTP 客户端使用
net/http 包提供了发送HTTP 请求的功能,可以通过http.Get()、http.Post() 等方法发送请求。以下是客户端的一些常见用法。
3.1 发送 GET 请求
最常用的HTTP 请求方法之一是GET,它用于从服务器获取资源。
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
// 发送 GET 请求
resp, err := http.Get("https://jsonplaceholder.typicode.com/posts")
if err !=nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
// 读取响应内容
body, err := ioutil.ReadAll(resp.Body)
if err !=nil {
fmt.Println("Error reading body:", err)
return
}
// 输出响应内容
fmt.Println("Response Body:",string(body))
}
解释:
·http.Get(url):发送GET 请求并返回*http.Response 对象。
·defer resp.Body.Close():在函数退出时关闭响应体,避免资源泄漏。
·ioutil.ReadAll():读取响应体并返回字节切片。
3.2 发送 POST 请求
POST 请求通常用于向服务器提交数据。
package main
import (
"bytes"
"fmt"
"net/http"
"io/ioutil"
)
func main() {
// 准备发送的数据
data := []byte(`{"title": "foo", "body": "bar", "userId": 1}`)
// 发送 POST 请求
resp, err := http.Post("https://jsonplaceholder.typicode.com/posts","application/json", bytes.NewBuffer(data))
if err !=nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
// 读取响应内容
body, err := ioutil.ReadAll(resp.Body)
if err !=nil {
fmt.Println("Error reading body:", err)
return
}
// 输出响应内容
fmt.Println("Response Body:",string(body))
}
解释:
·http.Post(url, contentType, body):发送POST 请求,contentType 是请求体的内容类型(如JSON),body 是请求体。
·bytes.NewBuffer(data):将数据包装为io.Reader,传递给http.Post()。
3.3 发送带有自定义头部的请求
你可以使用http.NewRequest() 创建自定义的HTTP 请求,并设置请求头。
package main
import (
"fmt"
"net/http"
"io/ioutil"
"log"
)
func main() {
// 创建自定义请求
req, err := http.NewRequest("GET","https://jsonplaceholder.typicode.com/posts",nil)
if err !=nil {
log.Fatal(err)
}
// 设置请求头
req.Header.Set("Authorization","Bearer my-token")
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err !=nil {
log.Fatal(err)
}
defer resp.Body.Close()
// 读取响应内容
body, err := ioutil.ReadAll(resp.Body)
if err !=nil {
log.Fatal(err)
}
// 输出响应内容
fmt.Println("Response Body:",string(body))
}
解释:
·http.NewRequest(method, url, body):创建一个新的HTTP 请求,可以设置请求方法、URL 和请求体。
·client.Do(req):使用自定义http.Client 发送请求。
·req.Header.Set():设置请求头。
4、 作为 HTTP 服务器使用
net/http 还可以用于构建HTTP 服务器,处理来自客户端的请求并生成响应。
4.1 创建简单的 HTTP 服务器
使用http.HandleFunc() 方法,你可以为不同的URL 路径指定处理函数。
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w,"Hello, %s!", r.URL.Path[1:])
}
func main() {
// 注册路由和处理函数
http.HandleFunc("/", handler)
// 启动 HTTP 服务器
fmt.Println("Starting server on :8080...")
if err := http.ListenAndServe(":8080",nil); err !=nil {
fmt.Println("Error starting server:", err)
}
}
解释:
·http.HandleFunc("/", handler):注册一个处理函数handler,它将处理所有来自/ 路径的请求。
·http.ListenAndServe(":8080", nil):启动一个HTTP 服务器,监听8080 端口,处理请求。
4.2 路由和多处理函数
你可以注册多个路由和对应的处理函数来处理不同的URL 路径。
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w,"Hello World!")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w,"About Us!")
}
func main() {
// 注册多个路由和处理函数
http.HandleFunc("/hello", helloHandler)
http.HandleFunc("/about", aboutHandler)
// 启动 HTTP 服务器
fmt.Println("Starting server on :8080...")
if err := http.ListenAndServe(":8080",nil); err !=nil {
fmt.Println("Error starting server:", err)
}
}
解释:
·通过http.HandleFunc("/path", handler) 注册多个路由,处理不同的请求路径。
5、 使用 HTTP 中间件
中间件是HTTP 处理过程中的一环,可以用来执行请求预处理、日志记录、身份验证等操作。Go 语言的net/http 包本身不直接提供中间件支持,但你可以通过包装现有的处理函数实现中间件。
5.1 创建简单的日志中间件
package main
import (
"fmt"
"net/http"
"time"
)
// 日志中间件
func logRequest(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
fmt.Printf("Request: %s %s, Duration: %v\n", r.Method, r.URL.Path, time.Since(start))
})
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w,"Hello World!")
}
func main() {
// 注册路由和处理函数
http.HandleFunc("/hello", helloHandler)
// 使用日志中间件
http.Handle("/hello", logRequest(http.HandlerFunc(helloHandler)))
// 启动 HTTP 服务器
fmt.Println("Starting server on :8080...")
if err := http.ListenAndServe(":8080",nil); err !=nil {
fmt.Println("Error starting server:", err)
}
}
解释:
·logRequest 是一个中间件,它包裹了请求处理函数,记录请求的开始时间和结束时间。
·http.Handle("/hello", logRequest(http.HandlerFunc(helloHandler))):将中间件应用到处理/hello 路径的请求。
6、 应用场景
·构建RESTful API:net/http 可以用来创建Web 服务端,处理 GET、POST、PUT、DELETE 等 HTTP 请求。
·Web 应用开发:你可以使用net/http 来开发简单的Web 应用,响应用户请求并返回动态页面。
·爬虫和数据抓取:net/http 适用于编写爬虫程序,通过发送HTTP 请求获取网页数据。
·客户端API 请求:通过net/http 可以方便地向其他服务器发送HTTP 请求,获取数据或与其他服务交互。
更多推荐

所有评论(0)