调整项目结构,factory只负责暴露方法,不实现业务细节

This commit is contained in:
2025-12-07 00:04:01 +08:00
parent b66f345281
commit 339920a940
23 changed files with 2165 additions and 1231 deletions

View File

@@ -2,16 +2,17 @@
## 概述
HTTP Restful工具提供了标准化的HTTP请求和响应处理功能采用Handler黑盒模式封装了`ResponseWriter``Request`提供简洁的API无需每次都传递这两个参数
HTTP Restful工具提供了标准化的HTTP请求和响应处理功能提供公共方法供外部调用,保持低耦合
## 功能特性
- **黑盒模式**:封装`ResponseWriter``Request`提供简洁的API
- **低耦合设计**提供公共方法不封装Handler结构
- **标准化的响应结构**`{code, message, timestamp, data}`
- **分离HTTP状态码和业务状态码**
- **支持分页响应**
- **提供便捷的请求参数解析方法**
- **支持JSON请求体解析**
- **Factory黑盒模式**:推荐使用 `factory.Success()` 等方法
## 响应结构
@@ -26,6 +27,18 @@ HTTP Restful工具提供了标准化的HTTP请求和响应处理功能采用H
}
```
**结构体类型(暴露在 factory 中):**
```go
// 在 factory 包中可以直接使用
type Response struct {
Code int `json:"code"` // 业务状态码0表示成功
Message string `json:"message"` // 响应消息
Timestamp int64 `json:"timestamp"` // 时间戳
Data interface{} `json:"data"` // 响应数据
}
```
### 分页响应结构
```json
@@ -42,9 +55,116 @@ HTTP Restful工具提供了标准化的HTTP请求和响应处理功能采用H
}
```
**结构体类型(暴露在 factory 中):**
```go
// 在 factory 包中可以直接使用
type PageData struct {
List interface{} `json:"list"` // 数据列表
Total int64 `json:"total"` // 总记录数
Page int `json:"page"` // 当前页码
PageSize int `json:"pageSize"` // 每页大小
}
type PageResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Timestamp int64 `json:"timestamp"`
Data *PageData `json:"data"`
}
```
### 使用暴露的结构体
外部项目可以直接使用 `factory.Response``factory.PageData` 等类型:
```go
import "git.toowon.com/jimmy/go-common/factory"
// 创建标准响应对象
response := factory.Response{
Code: 0,
Message: "success",
Data: userData,
}
// 创建分页数据对象
pageData := &factory.PageData{
List: users,
Total: 100,
Page: 1,
PageSize: 20,
}
// 传递给 Success 方法
fac.Success(w, pageData)
```
## 使用方法
### 1. 创建Handler
### 方式一使用Factory黑盒方法推荐
这是最简单的方式,直接使用 `factory.Success()` 等方法:
```go
import (
"net/http"
"git.toowon.com/jimmy/go-common/factory"
commonhttp "git.toowon.com/jimmy/go-common/http"
)
func GetUser(w http.ResponseWriter, r *http.Request) {
fac, _ := factory.NewFactoryFromFile("config.json")
// 获取查询参数(使用公共方法)
id := commonhttp.GetQueryInt64(r, "id", 0)
// 返回成功响应使用factory方法
fac.Success(w, data)
}
func CreateUser(w http.ResponseWriter, r *http.Request) {
fac, _ := factory.NewFactoryFromFile("config.json")
// 解析JSON使用公共方法
var req struct {
Name string `json:"name"`
}
if err := commonhttp.ParseJSON(r, &req); err != nil {
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
// 返回成功响应使用factory方法
fac.Success(w, data, "创建成功")
}
func GetUserList(w http.ResponseWriter, r *http.Request) {
fac, _ := factory.NewFactoryFromFile("config.json")
// 获取分页参数使用factory方法推荐
pagination := fac.ParsePaginationRequest(r)
page := pagination.GetPage()
pageSize := pagination.GetSize()
// 获取查询参数使用factory方法推荐
keyword := fac.GetQuery(r, "keyword", "")
// 查询数据
list, total := getDataList(keyword, page, pageSize)
// 返回分页响应使用factory方法
fac.SuccessPage(w, list, total, page, pageSize)
}
// 注册路由
http.HandleFunc("/user", GetUser)
http.HandleFunc("/users", GetUserList)
```
### 方式二:直接使用公共方法
如果不想使用Factory可以直接使用 `http` 包的公共方法:
```go
import (
@@ -52,154 +172,110 @@ import (
commonhttp "git.toowon.com/jimmy/go-common/http"
)
// 方式1使用HandleFunc包装器推荐最简洁
func GetUser(h *commonhttp.Handler) {
id := h.GetQueryInt64("id", 0)
h.Success(data)
func GetUser(w http.ResponseWriter, r *http.Request) {
// 获取查询参数
id := commonhttp.GetQueryInt64(r, "id", 0)
// 返回成功响应
commonhttp.Success(w, data)
}
http.HandleFunc("/user", commonhttp.HandleFunc(GetUser))
// 方式2手动创建Handler需要更多控制时
http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
h := commonhttp.NewHandler(w, r)
GetUser(h)
})
```
### 2. 成功响应
```go
func handler(h *commonhttp.Handler) {
// 简单成功响应data为nil
h.Success(nil)
// 带数据的成功响应
data := map[string]interface{}{
"id": 1,
"name": "test",
func CreateUser(w http.ResponseWriter, r *http.Request) {
// 解析JSON
var req struct {
Name string `json:"name"`
}
if err := commonhttp.ParseJSON(r, &req); err != nil {
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
h.Success(data)
// 带消息的成功响应
h.SuccessWithMessage("操作成功", data)
// 返回成功响应
commonhttp.Success(w, data, "创建成功")
}
```
### 3. 错误响应
### 成功响应
```go
func handler(h *commonhttp.Handler) {
// 业务错误HTTP 200业务code非0
h.Error(1001, "用户不存在")
// 系统错误HTTP 500
h.SystemError("服务器内部错误")
// 其他HTTP错误状态码使用WriteJSON直接指定
// 请求错误HTTP 400
h.WriteJSON(http.StatusBadRequest, 400, "请求参数错误", nil)
// 未授权HTTP 401
h.WriteJSON(http.StatusUnauthorized, 401, "未登录", nil)
// 禁止访问HTTP 403
h.WriteJSON(http.StatusForbidden, 403, "无权限访问", nil)
// 未找到HTTP 404
h.WriteJSON(http.StatusNotFound, 404, "资源不存在", nil)
}
// 使用Factory推荐
fac.Success(w, data) // 只有数据,使用默认消息 "success"
fac.Success(w, data, "操作成功") // 数据+消息
// 或直接使用公共方法
commonhttp.Success(w, data) // 只有数据
commonhttp.Success(w, data, "操作成功") // 数据+消息
```
### 4. 分页响应
### 错误响应
```go
func handler(h *commonhttp.Handler) {
// 获取分页参数
pagination := h.ParsePaginationRequest()
page := pagination.GetPage()
pageSize := pagination.GetSize()
// 查询数据(示例)
list, total := getDataList(page, pageSize)
// 返回分页响应(使用默认消息)
h.SuccessPage(list, total, page, pageSize)
// 返回分页响应(自定义消息)
h.SuccessPage(list, total, page, pageSize, "查询成功")
}
// 使用Factory推荐
fac.Error(w, 1001, "用户不存在") // 业务错误HTTP 200业务code非0
fac.SystemError(w, "服务器内部错误") // 系统错误HTTP 500
// 或直接使用公共方法
commonhttp.Error(w, 1001, "用户不存在")
commonhttp.SystemError(w, "服务器内部错误")
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数错误", nil) // 自定义HTTP状态码仅公共方法
```
### 5. 解析请求
### 分页响应
```go
// 使用Factory推荐
fac.SuccessPage(w, list, total, page, pageSize)
fac.SuccessPage(w, list, total, page, pageSize, "查询成功")
// 或直接使用公共方法
commonhttp.SuccessPage(w, list, total, page, pageSize)
commonhttp.SuccessPage(w, list, total, page, pageSize, "查询成功")
```
### 解析请求
#### 解析JSON请求体
```go
func handler(h *commonhttp.Handler) {
type CreateUserRequest struct {
Name string `json:"name"`
Email string `json:"email"`
}
var req CreateUserRequest
if err := h.ParseJSON(&req); err != nil {
h.WriteJSON(http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
// 使用req...
// 使用公共方法
var req struct {
Name string `json:"name"`
Email string `json:"email"`
}
if err := commonhttp.ParseJSON(r, &req); err != nil {
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
```
#### 获取查询参数
```go
func handler(h *commonhttp.Handler) {
// 获取字符串参数
name := h.GetQuery("name", "")
email := h.GetQuery("email", "default@example.com")
// 获取整数参数
id := h.GetQueryInt("id", 0)
age := h.GetQueryInt("age", 18)
// 获取int64参数
userId := h.GetQueryInt64("userId", 0)
// 获取布尔参数
isActive := h.GetQueryBool("isActive", false)
// 获取浮点数参数
price := h.GetQueryFloat64("price", 0.0)
}
// 使用公共方法
name := commonhttp.GetQuery(r, "name", "")
id := commonhttp.GetQueryInt(r, "id", 0)
userId := commonhttp.GetQueryInt64(r, "userId", 0)
isActive := commonhttp.GetQueryBool(r, "isActive", false)
price := commonhttp.GetQueryFloat64(r, "price", 0.0)
```
#### 获取表单参数
```go
func handler(h *commonhttp.Handler) {
// 获取表单字符串
name := h.GetFormValue("name", "")
// 获取表单整数
age := h.GetFormInt("age", 0)
// 获取表单int64
userId := h.GetFormInt64("userId", 0)
// 获取表单布尔值
isActive := h.GetFormBool("isActive", false)
}
// 使用公共方法
name := commonhttp.GetFormValue(r, "name", "")
age := commonhttp.GetFormInt(r, "age", 0)
userId := commonhttp.GetFormInt64(r, "userId", 0)
isActive := commonhttp.GetFormBool(r, "isActive", false)
```
#### 获取请求头
```go
func handler(h *commonhttp.Handler) {
token := h.GetHeader("Authorization", "")
contentType := h.GetHeader("Content-Type", "application/json")
}
// 使用公共方法
token := commonhttp.GetHeader(r, "Authorization", "")
contentType := commonhttp.GetHeader(r, "Content-Type", "application/json")
```
#### 获取分页参数
@@ -207,71 +283,55 @@ func handler(h *commonhttp.Handler) {
**方式1使用 PaginationRequest 结构(推荐)**
```go
func handler(h *commonhttp.Handler) {
// 定义请求结构(包含分页字段)
type ListUserRequest struct {
Keyword string `json:"keyword"`
commonhttp.PaginationRequest // 嵌入分页请求结构
}
// 从JSON请求体解析分页字段会自动解析
var req ListUserRequest
if err := h.ParseJSON(&req); err != nil {
h.WriteJSON(http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
// 使用分页方法
page := req.GetPage() // 获取页码默认1
size := req.GetSize() // 获取每页数量默认20最大100优先使用page_size
offset := req.GetOffset() // 计算偏移量
// 定义请求结构(包含分页字段)
type ListUserRequest struct {
Keyword string `json:"keyword"`
commonhttp.PaginationRequest // 嵌入分页请求结构
}
// 或者从查询参数/form解析分页
func handler(h *commonhttp.Handler) {
pagination := h.ParsePaginationRequest()
page := pagination.GetPage()
size := pagination.GetSize()
offset := pagination.GetOffset()
// 从JSON请求体解析分页字段会自动解析)
var req ListUserRequest
if err := commonhttp.ParseJSON(r, &req); err != nil {
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
// 使用分页方法
page := req.GetPage() // 获取页码默认1
size := req.GetSize() // 获取每页数量默认20最大100优先使用page_size
offset := req.GetOffset() // 计算偏移量
```
**方式2从查询参数/form解析分页**
```go
// 使用公共方法
pagination := commonhttp.ParsePaginationRequest(r)
page := pagination.GetPage()
size := pagination.GetSize()
offset := pagination.GetOffset()
```
#### 获取时区
```go
func handler(h *commonhttp.Handler) {
// 从请求的context中获取时区
// 如果使用了middleware.Timezone中间件可以从context中获取时区信息
// 如果未设置,返回默认时区 AsiaShanghai
timezone := h.GetTimezone()
}
```
### 6. 访问原始对象
如果需要访问原始的`ResponseWriter``Request`
```go
func handler(h *commonhttp.Handler) {
// 获取原始ResponseWriter
w := h.ResponseWriter()
// 获取原始Request
r := h.Request()
// 获取Context
ctx := h.Context()
}
// 使用公共方法
// 如果使用了middleware.Timezone中间件可以从context中获取时区信息
// 如果未设置,返回默认时区 AsiaShanghai
timezone := commonhttp.GetTimezone(r)
```
## 完整示例
### 使用Factory推荐
```go
package main
import (
"log"
"net/http"
"git.toowon.com/jimmy/go-common/factory"
commonhttp "git.toowon.com/jimmy/go-common/http"
)
@@ -283,91 +343,97 @@ type User struct {
}
// 用户列表接口
func GetUserList(h *commonhttp.Handler) {
// 获取分页参数
pagination := h.ParsePaginationRequest()
func GetUserList(w http.ResponseWriter, r *http.Request) {
fac, _ := factory.NewFactoryFromFile("config.json")
// 获取分页参数(使用公共方法)
pagination := commonhttp.ParsePaginationRequest(r)
page := pagination.GetPage()
pageSize := pagination.GetSize()
// 获取查询参数
keyword := h.GetQuery("keyword", "")
// 获取查询参数(使用公共方法)
keyword := commonhttp.GetQuery(r, "keyword", "")
// 查询数据
users, total := queryUsers(keyword, page, pageSize)
// 返回分页响应
h.SuccessPage(users, total, page, pageSize)
// 返回分页响应使用factory方法
fac.SuccessPage(w, users, total, page, pageSize)
}
// 创建用户接口
func CreateUser(h *commonhttp.Handler) {
// 解析请求体
func CreateUser(w http.ResponseWriter, r *http.Request) {
fac, _ := factory.NewFactoryFromFile("config.json")
// 解析请求体(使用公共方法)
var req struct {
Name string `json:"name"`
Email string `json:"email"`
}
if err := h.ParseJSON(&req); err != nil {
h.WriteJSON(http.StatusBadRequest, 400, "请求参数解析失败", nil)
if err := commonhttp.ParseJSON(r, &req); err != nil {
fac.WriteJSON(w, http.StatusBadRequest, 400, "请求参数解析失败", nil)
return
}
// 参数验证
if req.Name == "" {
h.Error(1001, "用户名不能为空")
fac.Error(w, 1001, "用户名不能为空")
return
}
// 创建用户
user, err := createUser(req.Name, req.Email)
if err != nil {
h.SystemError("创建用户失败")
fac.SystemError(w, "创建用户失败")
return
}
// 返回成功响应
h.SuccessWithMessage("创建成功", user)
// 返回成功响应使用factory方法
fac.Success(w, user, "创建成功")
}
// 获取用户详情接口
func GetUser(h *commonhttp.Handler) {
// 获取查询参数
id := h.GetQueryInt64("id", 0)
func GetUser(w http.ResponseWriter, r *http.Request) {
fac, _ := factory.NewFactoryFromFile("config.json")
// 获取查询参数使用factory方法推荐
id := fac.GetQueryInt64(r, "id", 0)
if id == 0 {
h.WriteJSON(http.StatusBadRequest, 400, "用户ID不能为空", nil)
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "用户ID不能为空", nil)
return
}
// 查询用户
user, err := getUserByID(id)
if err != nil {
h.SystemError("查询用户失败")
fac.SystemError(w, "查询用户失败")
return
}
if user == nil {
h.Error(1002, "用户不存在")
fac.Error(w, 1002, "用户不存在")
return
}
h.Success(user)
// 返回成功响应使用factory方法
fac.Success(w, user)
}
func main() {
// 使用HandleFunc包装器推荐
http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
switch h.Request().Method {
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
GetUserList(h)
GetUserList(w, r)
case http.MethodPost:
CreateUser(h)
CreateUser(w, r)
default:
h.WriteJSON(http.StatusMethodNotAllowed, 405, "方法不支持", nil)
commonhttp.WriteJSON(w, http.StatusMethodNotAllowed, 405, "方法不支持", nil)
}
}))
})
http.HandleFunc("/user", commonhttp.HandleFunc(GetUser))
http.HandleFunc("/user", GetUser)
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
@@ -376,53 +442,93 @@ func main() {
## API 参考
### Handler结构
### Factory HTTP响应结构体暴露给外部项目使用
Handler封装了`ResponseWriter``Request`提供更简洁的API。
#### Response
```go
type Handler struct {
w http.ResponseWriter
r *http.Request
}
```
标准响应结构体,外部项目可以直接使用 `factory.Response`
### 创建Handler
#### NewHandler(w http.ResponseWriter, r *http.Request) *Handler
创建Handler实例。
#### HandleFunc(fn func(*Handler)) http.HandlerFunc
将Handler函数转换为标准的http.HandlerFunc便捷包装器
**字段:**
- `Code`: 业务状态码0表示成功
- `Message`: 响应消息
- `Timestamp`: 时间戳Unix时间戳
- `Data`: 响应数据
**示例:**
```go
http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
h.Success(data)
}))
response := factory.Response{
Code: 0,
Message: "success",
Data: userData,
}
```
### Handler响应方法
#### PageData
#### (h *Handler) Success(data interface{})
分页数据结构体,外部项目可以直接使用 `factory.PageData`
**字段:**
- `List`: 数据列表
- `Total`: 总记录数
- `Page`: 当前页码
- `PageSize`: 每页大小
**示例:**
```go
pageData := &factory.PageData{
List: users,
Total: 100,
Page: 1,
PageSize: 20,
}
fac.Success(w, pageData)
```
#### PageResponse
分页响应结构体,外部项目可以直接使用 `factory.PageResponse`
**字段:**
- `Code`: 业务状态码
- `Message`: 响应消息
- `Timestamp`: 时间戳
- `Data`: 分页数据(*PageData
### Factory HTTP响应方法推荐使用
#### (f *Factory) Success(w http.ResponseWriter, data interface{}, message ...string)
成功响应HTTP 200业务code 0。
#### (h *Handler) SuccessWithMessage(message string, data interface{})
**参数:**
- `data`: 响应数据可以为nil
- `message`: 响应消息(可选),如果为空则使用默认消息 "success"
带消息的成功响应。
**示例:**
```go
fac.Success(w, data) // 只有数据,使用默认消息 "success"
fac.Success(w, data, "操作成功") // 数据+消息
```
#### (h *Handler) Error(code int, message string)
#### (f *Factory) Error(w http.ResponseWriter, code int, message string)
业务错误响应HTTP 200业务code非0。
#### (h *Handler) SystemError(message string)
**示例:**
```go
fac.Error(w, 1001, "用户不存在")
```
#### (f *Factory) SystemError(w http.ResponseWriter, message string)
系统错误响应HTTP 500业务code 500。
#### (h *Handler) WriteJSON(httpCode, code int, message string, data interface{})
**示例:**
```go
fac.SystemError(w, "服务器内部错误")
```
#### (f *Factory) WriteJSON(w http.ResponseWriter, httpCode, code int, message string, data interface{})
写入JSON响应自定义
@@ -432,7 +538,17 @@ http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
- `message`: 响应消息
- `data`: 响应数据
#### (h *Handler) SuccessPage(list interface{}, total int64, page, pageSize int, message ...string)
**说明:**
- 此方法不在 Factory 中,直接使用 `commonhttp.WriteJSON()`
- 用于需要自定义HTTP状态码的场景如 400, 401, 403, 404 等)
**示例:**
```go
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数错误", nil)
commonhttp.WriteJSON(w, http.StatusUnauthorized, 401, "未登录", nil)
```
#### (f *Factory) SuccessPage(w http.ResponseWriter, list interface{}, total int64, page, pageSize int, message ...string)
分页成功响应。
@@ -443,53 +559,81 @@ http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
- `pageSize`: 每页大小
- `message`: 响应消息(可选,如果为空则使用默认消息 "success"
### Handler请求解析方法
**示例:**
```go
fac.SuccessPage(w, users, total, page, pageSize)
fac.SuccessPage(w, users, total, page, pageSize, "查询成功")
```
#### (h *Handler) ParseJSON(v interface{}) error
### HTTP公共方法直接使用
#### WriteJSON(w http.ResponseWriter, httpCode, code int, message string, data interface{})
写入JSON响应自定义HTTP状态码和业务状态码
**说明:**
- 此方法不在 Factory 中,直接使用 `commonhttp.WriteJSON()`
- 用于需要自定义HTTP状态码的场景如 400, 401, 403, 404 等)
**示例:**
```go
commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "请求参数错误", nil)
commonhttp.WriteJSON(w, http.StatusUnauthorized, 401, "未登录", nil)
```
#### ParseJSON(r *http.Request, v interface{}) error
解析JSON请求体。
#### (h *Handler) GetQuery(key, defaultValue string) string
**示例:**
```go
var req CreateUserRequest
if err := commonhttp.ParseJSON(r, &req); err != nil {
// 处理错误
}
```
#### GetQuery(r *http.Request, key, defaultValue string) string
获取查询参数(字符串)。
#### (h *Handler) GetQueryInt(key string, defaultValue int) int
#### GetQueryInt(r *http.Request, key string, defaultValue int) int
获取查询参数(整数)。
#### (h *Handler) GetQueryInt64(key string, defaultValue int64) int64
#### GetQueryInt64(r *http.Request, key string, defaultValue int64) int64
获取查询参数int64
#### (h *Handler) GetQueryBool(key string, defaultValue bool) bool
#### GetQueryBool(r *http.Request, key string, defaultValue bool) bool
获取查询参数(布尔值)。
#### (h *Handler) GetQueryFloat64(key string, defaultValue float64) float64
#### GetQueryFloat64(r *http.Request, key string, defaultValue float64) float64
获取查询参数(浮点数)。
#### (h *Handler) GetFormValue(key, defaultValue string) string
#### GetFormValue(r *http.Request, key, defaultValue string) string
获取表单值(字符串)。
#### (h *Handler) GetFormInt(key string, defaultValue int) int
#### GetFormInt(r *http.Request, key string, defaultValue int) int
获取表单值(整数)。
#### (h *Handler) GetFormInt64(key string, defaultValue int64) int64
#### GetFormInt64(r *http.Request, key string, defaultValue int64) int64
获取表单值int64
#### (h *Handler) GetFormBool(key string, defaultValue bool) bool
#### GetFormBool(r *http.Request, key string, defaultValue bool) bool
获取表单值(布尔值)。
#### (h *Handler) GetHeader(key, defaultValue string) string
#### GetHeader(r *http.Request, key, defaultValue string) string
获取请求头。
#### (h *Handler) ParsePaginationRequest() *PaginationRequest
#### ParsePaginationRequest(r *http.Request) *PaginationRequest
从请求中解析分页参数。
@@ -498,7 +642,7 @@ http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
- 优先级:查询参数 > form表单
- 如果请求体是JSON格式且包含分页字段建议先使用`ParseJSON`解析完整请求体到包含`PaginationRequest`的结构体中
#### (h *Handler) GetTimezone() string
#### GetTimezone(r *http.Request) string
从请求的context中获取时区。
@@ -506,19 +650,39 @@ http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
- 如果使用了middleware.Timezone中间件可以从context中获取时区信息
- 如果未设置,返回默认时区 AsiaShanghai
### Handler访问原始对象
#### Success(w http.ResponseWriter, data interface{}, message ...string)
#### (h *Handler) ResponseWriter() http.ResponseWriter
成功响应(公共方法)。
获取原始的ResponseWriter需要时使用
**参数:**
- `data`: 响应数据可以为nil
- `message`: 响应消息(可选),如果为空则使用默认消息 "success"
#### (h *Handler) Request() *http.Request
**示例:**
```go
commonhttp.Success(w, data) // 只有数据
commonhttp.Success(w, data, "操作成功") // 数据+消息
```
获取原始的Request需要时使用
#### Error(w http.ResponseWriter, code int, message string)
#### (h *Handler) Context() context.Context
错误响应(公共方法)。
获取请求的Context。
#### SystemError(w http.ResponseWriter, message string)
系统错误响应(公共方法)。
#### WriteJSON(w http.ResponseWriter, httpCode, code int, message string, data interface{})
写入JSON响应公共方法不在Factory中
**说明:**
- 用于需要自定义HTTP状态码的场景
- 直接使用 `commonhttp.WriteJSON()`,不在 Factory 中
#### SuccessPage(w http.ResponseWriter, list interface{}, total int64, page, pageSize int, message ...string)
分页成功响应(公共方法)。
### 分页请求结构
@@ -575,10 +739,14 @@ http.HandleFunc("/users", commonhttp.HandleFunc(func(h *commonhttp.Handler) {
- 使用`SystemError`返回系统错误HTTP 500
- 其他HTTP错误状态码400, 401, 403, 404等使用`WriteJSON`方法直接指定
5. **黑盒模式**
- 所有功能都通过Handler对象调用无需传递`w``r`参数
- 代码更简洁,减少调用方工作量
5. **推荐使用Factory**
- 使用 `factory.Success()` 等方法,代码更简洁
- 直接使用 `http` 包的公共方法,保持低耦合
- 不需要Handler结构减少不必要的封装
## 示例
完整示例请参考 `examples/http_handler_example.go`
完整示例请参考
- `examples/http_handler_example.go` - 使用Factory和公共方法
- `examples/http_pagination_example.go` - 分页示例
- `examples/factory_blackbox_example.go` - Factory黑盒模式示例