Files
golang/golang-learning/10-projects/03-web-server/server/handlers.go
2025-08-24 13:01:09 +08:00

370 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
handlers.go - 请求处理器
实现了各种HTTP请求的处理逻辑
*/
package server
import (
"encoding/json"
"net/http"
"runtime"
"strconv"
"time"
"webserver/models"
"github.com/gorilla/mux"
)
// Response 通用响应结构
type Response struct {
Status string `json:"status"`
Message string `json:"message,omitempty"`
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
Count int `json:"count,omitempty"`
}
// HealthResponse 健康检查响应
type HealthResponse struct {
Status string `json:"status"`
Timestamp string `json:"timestamp"`
Uptime string `json:"uptime"`
Version string `json:"version"`
}
// StatsResponse 统计信息响应
type StatsResponse struct {
Status string `json:"status"`
Timestamp string `json:"timestamp"`
Uptime string `json:"uptime"`
Version string `json:"version"`
GoVersion string `json:"go_version"`
NumCPU int `json:"num_cpu"`
NumGoroutine int `json:"num_goroutine"`
MemStats runtime.MemStats `json:"mem_stats"`
}
var (
startTime = time.Now()
version = "1.0.0"
)
// HomeHandler 首页处理器
func HomeHandler(w http.ResponseWriter, r *http.Request) {
html := `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Go Web服务器</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; background-color: #f5f5f5; }
.container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
h1 { color: #333; text-align: center; }
.api-list { background: #f8f9fa; padding: 20px; border-radius: 5px; margin: 20px 0; }
.api-item { margin: 10px 0; padding: 10px; background: white; border-left: 4px solid #007bff; }
.method { font-weight: bold; color: #007bff; }
.endpoint { font-family: monospace; background: #e9ecef; padding: 2px 6px; border-radius: 3px; }
.description { color: #666; margin-top: 5px; }
</style>
</head>
<body>
<div class="container">
<h1>🚀 Go Web服务器</h1>
<p>欢迎使用Go语言编写的简单Web服务器这个项目演示了HTTP服务器、RESTful API、JSON处理等功能。</p>
<h2>📚 API接口</h2>
<div class="api-list">
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/health</span>
<div class="description">健康检查</div>
</div>
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/api/stats</span>
<div class="description">服务器统计信息</div>
</div>
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/api/users</span>
<div class="description">获取所有用户</div>
</div>
<div class="api-item">
<span class="method">POST</span> <span class="endpoint">/api/users</span>
<div class="description">创建新用户</div>
</div>
<div class="api-item">
<span class="method">GET</span> <span class="endpoint">/api/users/{id}</span>
<div class="description">获取指定用户</div>
</div>
<div class="api-item">
<span class="method">PUT</span> <span class="endpoint">/api/users/{id}</span>
<div class="description">更新用户信息</div>
</div>
<div class="api-item">
<span class="method">DELETE</span> <span class="endpoint">/api/users/{id}</span>
<div class="description">删除用户</div>
</div>
</div>
<h2>🛠️ 使用示例</h2>
<pre style="background: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto;">
# 获取所有用户
curl http://localhost:8080/api/users
# 创建新用户
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","email":"zhangsan@example.com","age":25}'
# 健康检查
curl http://localhost:8080/health
</pre>
</div>
</body>
</html>`
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusOK)
w.Write([]byte(html))
}
// HealthHandler 健康检查处理器
func HealthHandler(w http.ResponseWriter, r *http.Request) {
uptime := time.Since(startTime)
response := HealthResponse{
Status: "healthy",
Timestamp: time.Now().Format(time.RFC3339),
Uptime: uptime.String(),
Version: version,
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// StatsHandler 统计信息处理器
func StatsHandler(w http.ResponseWriter, r *http.Request) {
uptime := time.Since(startTime)
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
response := StatsResponse{
Status: "success",
Timestamp: time.Now().Format(time.RFC3339),
Uptime: uptime.String(),
Version: version,
GoVersion: runtime.Version(),
NumCPU: runtime.NumCPU(),
NumGoroutine: runtime.NumGoroutine(),
MemStats: memStats,
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// GetUsersHandler 获取所有用户
func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
users, err := models.GetAllUsers()
if err != nil {
sendErrorResponse(w, "获取用户列表失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Data: users,
Count: len(users),
}
sendJSONResponse(w, response, http.StatusOK)
}
// GetUserHandler 获取指定用户
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
sendErrorResponse(w, "无效的用户ID", http.StatusBadRequest)
return
}
user, err := models.GetUserByID(id)
if err != nil {
sendErrorResponse(w, "用户不存在", http.StatusNotFound)
return
}
response := Response{
Status: "success",
Data: user,
}
sendJSONResponse(w, response, http.StatusOK)
}
// CreateUserHandler 创建新用户
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
var user models.User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
sendErrorResponse(w, "无效的JSON数据", http.StatusBadRequest)
return
}
// 验证用户数据
if err := user.Validate(); err != nil {
sendErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
// 创建用户
createdUser, err := models.CreateUser(user)
if err != nil {
sendErrorResponse(w, "创建用户失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Message: "用户创建成功",
Data: createdUser,
}
sendJSONResponse(w, response, http.StatusCreated)
}
// UpdateUserHandler 更新用户信息
func UpdateUserHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
sendErrorResponse(w, "无效的用户ID", http.StatusBadRequest)
return
}
var user models.User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
sendErrorResponse(w, "无效的JSON数据", http.StatusBadRequest)
return
}
// 设置用户ID
user.ID = id
// 验证用户数据
if err := user.Validate(); err != nil {
sendErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
// 更新用户
updatedUser, err := models.UpdateUser(user)
if err != nil {
sendErrorResponse(w, "更新用户失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Message: "用户更新成功",
Data: updatedUser,
}
sendJSONResponse(w, response, http.StatusOK)
}
// DeleteUserHandler 删除用户
func DeleteUserHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
sendErrorResponse(w, "无效的用户ID", http.StatusBadRequest)
return
}
if err := models.DeleteUser(id); err != nil {
sendErrorResponse(w, "删除用户失败", http.StatusInternalServerError)
return
}
response := Response{
Status: "success",
Message: "用户删除成功",
}
sendJSONResponse(w, response, http.StatusOK)
}
// APIDocHandler API文档处理器
func APIDocHandler(w http.ResponseWriter, r *http.Request) {
doc := map[string]interface{}{
"title": "Go Web服务器 API",
"version": version,
"description": "一个简单的RESTful API服务器",
"endpoints": map[string]interface{}{
"health": map[string]string{
"method": "GET",
"path": "/health",
"description": "健康检查",
},
"stats": map[string]string{
"method": "GET",
"path": "/api/stats",
"description": "服务器统计信息",
},
"users": map[string]interface{}{
"list": map[string]string{
"method": "GET",
"path": "/api/users",
"description": "获取所有用户",
},
"get": map[string]string{
"method": "GET",
"path": "/api/users/{id}",
"description": "获取指定用户",
},
"create": map[string]string{
"method": "POST",
"path": "/api/users",
"description": "创建新用户",
},
"update": map[string]string{
"method": "PUT",
"path": "/api/users/{id}",
"description": "更新用户信息",
},
"delete": map[string]string{
"method": "DELETE",
"path": "/api/users/{id}",
"description": "删除用户",
},
},
},
}
sendJSONResponse(w, doc, http.StatusOK)
}
// sendJSONResponse 发送JSON响应
func sendJSONResponse(w http.ResponseWriter, data interface{}, statusCode int) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
if err := json.NewEncoder(w).Encode(data); err != nil {
http.Error(w, "JSON编码失败", http.StatusInternalServerError)
}
}
// sendErrorResponse 发送错误响应
func sendErrorResponse(w http.ResponseWriter, message string, statusCode int) {
response := Response{
Status: "error",
Error: message,
}
sendJSONResponse(w, response, statusCode)
}