370 lines
10 KiB
Go
370 lines
10 KiB
Go
/*
|
||
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)
|
||
}
|