在 Golang 中,通过 HTTP POST 请求获取 JSON 数据通常分为 服务端接收 和 客户端发送 两种场景。以下是详细示例:
1. 服务端接收 JSON 数据
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func handlePost(w http.ResponseWriter, r *http.Request) {
// 1. 检查请求方法是否为 POST
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
fmt.Fprintf(w, "Invalid request method")
return
}
// 2. 解析 JSON Body
var user User
err := json.NewDecoder(r.Body).Decode(&user)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "Error decoding JSON: %v", err)
return
}
defer r.Body.Close()
// 3. 处理数据(示例:打印并返回)
fmt.Printf("Received user: %+v\n", user)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
}
func main() {
http.HandleFunc("/user", handlePost)
fmt.Println("Server listening on :8080...")
http.ListenAndServe(":8080", nil)
}
关键点说明:
r.Body
: POST 请求的原始数据流,需通过json.NewDecoder
解析。defer r.Body.Close()
: 确保关闭请求体,避免资源泄漏。- 错误处理: 检查 HTTP Method、JSON 解析失败等场景。
2. 客户端发送 JSON 数据
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
data := User{Name: "Alice", Age: 25}
// 1. 将结构体编码为 JSON
jsonData, err := json.Marshal(data)
if err != nil {
panic(err)
}
// 2. 发送 POST 请求
resp, err := http.Post(
"http://localhost:8080/user",
"application/json",
bytes.NewBuffer(jsonData),
)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// 3. 读取响应
var result map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
panic(err)
}
fmt.Println("Response:", result)
}
关键点说明:
http.Post
:
参数依次为目标 URL、Content-Type(必须为application/json
)、JSON 数据流。- 错误处理: 检查 JSON编码、网络请求、响应解析等步骤。
常见问题排查
- 415 Unsupported Media Type
确保客户端设置正确的 Header:
req.Header.Set("Content-Type", "application/json")
- 空 Body
检查客户端是否实际发送了 JSON,或服务端是否未读取r.Body
。 - 性能优化
高频请求时,复用http.Client
:client := &http.Client{} resp, err := client.Post(...)
如果需要更复杂的场景(如文件上传、JWT验证),可以进一步扩展逻辑。
内容由零声教学AI助手提供,问题来源于学员提问