如何使用Golang构建Web服务器_使用net/http处理请求和响应
技术百科
P粉602998670
发布时间:2025-12-20
浏览: 次 Go 的 net/http 包内置轻量,几行代码即可启动 Web 服务器;通过 http.HandleFunc 注册处理器,用 http.ListenAndServe 监听端口;请求参数可从 r.URL.Query()、r.FormValue() 或 json.NewDecoder(r.Body) 获取;响应需用 w.WriteHeader() 设状态码、w.Header().Set() 设头;路由可用默认 ServeMux 或 gorilla/mux 等第三方库;中间件通过包装 http.Handler 实现。
用 Go 的 net/http 包构建 Web 服务器非常直接——它内置、轻量、无需额外依赖,几行代码就能跑起一个可工作的服务。
快速启动一个基础 HTTP 服务器
Go 标准库的 http.ListenAndServe 是入口。它监听指定地址(如 :8080),并把请求分发给注册的处理器(Handler)。
- 最简写法:用
http.HandleFunc注册路径和处理函数 - 处理函数必须符合
func(http.ResponseWriter, *http.Request)签
名 -
ResponseWriter用于写响应头和响应体;*http.Request提供请求方法、URL、Header、Body 等信息
示例:
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from Go!")
}
func main() {
http.HandleFunc("/hello", helloHandler)
http.ListenAndServe(":8080", nil)
}
运行后访问 http://localhost:8080/hello 即可看到响应。
读取请求参数和数据
常见需求包括获取 URL 查询参数、表单数据、JSON 请求体等,*http.Request 提供了对应方法:
-
r.URL.Query().Get("key"):获取 query string 参数(如/search?q=go中的q) -
r.FormValue("name"):自动解析application/x-www-form-urlencoded或multipart/form-data表单字段(会隐式调用ParseForm) -
json.NewDecoder(r.Body).Decode(&data):读取 JSON 请求体(注意:r.Body只能读一次,需提前检查Content-Type)
小提示:如果同时需要 query 和 form 数据,建议显式调用 r.ParseForm(),再统一从 r.Form 取值。
设置响应状态码与 Header
默认响应状态是 200 OK,但实际开发中常需自定义:
- 用
w.WriteHeader(http.StatusNotFound)设置非 200 状态码(必须在写入响应体前调用) - 用
w.Header().Set("Content-Type", "application/json; charset=utf-8")设置响应头 - 对 JSON 响应,推荐设
Content-Type并用json.NewEncoder(w).Encode(data)安全输出
错误响应示例:
func apiHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Only POST allowed"))
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
路由进阶:用 ServeMux 或第三方路由器
http.DefaultServeMux 是默认的多路复用器,支持前缀匹配(如 /api/)和精确路径匹配,但不支持动态路径(如 /user/:id)。
- 可创建自定义
http.ServeMux实例,避免污染全局默认 mux - 若需 RESTful 路由(带变量、中间件等),可引入轻量库如
gorilla/mux或chi,它们仍基于net/http接口,无缝兼容 - 所有处理器最终都实现
http.Handler接口,因此可自由组合中间件(如日志、CORS、认证)
例如加个简单日志中间件:
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("→ %s %s\n", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/hello", helloHandler)
http.ListenAndServe(":8080", loggingMiddleware(mux))
}
net/http 足够支撑中小型 API 和静态服务,理解其 Handler 模型和生命周期是写出健壮服务的关键。不复杂但容易忽略细节。
# ai
# 就能
# 表单
# 但不
# 进阶
# 第三方
# 自定义
# app
# 必须符合
# 并把
# 端口
# http
# js
# json
# go
# golang
# 路由
# String
# 标准库
# 路由器
# 接口
# 状态码
# 处理器
# 中间件
# restful
# 小提示
# 几行
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Go 中实现 Python urllib.quot
- Windows10系统怎么查看系统版本_Win10
- 如何使用Golang搭建Web开发环境_快速启动H
- VSC怎么创建PHP项目_从零开始搭建项目的步骤【
- Windows7怎么找回经典开始菜单_Window
- Win10如何优化内存使用_Win10内存优化技巧
- Win11如何设置系统声音_Win11系统声音调整
- Win11怎么关闭系统推荐内容_Windows11
- Win11怎么自动隐藏任务栏_Win11全屏显示设
- How to Properly Use NumPy
- mac怎么打开终端_MAC终端Terminal使用
- Python对象生命周期管理_创建销毁解析【教程】
- LINUX如何查看文件类型_Linux中file命
- 如何在 Go 应用中实现自动错误恢复与进程重启机制
- Python函数缓存机制_lru_cache解析【
- C++ STL算法库怎么用?C++常用算法函数(s
- 如何使用正则表达式批量替换重复的“-”模式为固定字
- Win11怎么关闭键盘按键音_Win11禁用打字声
- 如何在Golang中指定模块版本_使用go.mod
- mac怎么安装pip_MAC Python pip
- Python lxml的etree和Element
- c++如何使用std::bind绑定函数参数_c+
- Python集合操作技巧_高效去重解析【教程】
- Win11搜索栏无法输入_解决Win11开始菜单搜
- Windows 11无法安全删除U盘提示设备正在使
- 如何在Golang中使用log包输出不同级别日志_
- 如何在Golang中优化文件读写性能_使用缓冲和并
- GML (Geography Markup Lan
- Win10怎么设置开机密码_Windows10账户
- Win11怎么开启自动HDR画质_Windows1
- 如何使用Golang实现负载均衡_分发请求到多个服
- 如何使用Golang实现微服务事件驱动_使用消息总
- Win11怎么设置按流量计费_Win11限制后台流
- Win11怎么关闭自动调节亮度 Win11禁用内容
- php转mp4怎么设置帧率_调整php生成mp4视
- Windows 11如何查看系统激活密钥_Wind
- WindowsUSB驱动安装异常怎么办_USB驱动
- Windows怎样关闭开始菜单推荐广告_Windo
- Mac如何开启夜览模式_Mac护眼模式设置与定时
- php删除数据怎么软删除_添加is_del字段标记
- 如何使用 Python 合并文件夹内多个 Exce
- c++如何打印函数堆栈信息_c++ backtra
- php查询数据怎么分组_groupby分组查询配合
- 如何在Golang中实现WebSocket广播_使
- Linux怎么实现内网穿透_Linux安装Frp客
- 如何在Golang中写入JSON文件_保存结构体数
- 如何在 Django 中修改用户密码后保持会话不丢
- Python字符串处理进阶_切片方法解析【指导】
- php485返回空数组怎么回事_php485数据接
- MAC如何修改默认应用程序_MAC文件后缀关联设置

名
QQ客服