将工厂改成黑盒模式,降低用户使用成本
This commit is contained in:
279
http/handler.go
Normal file
279
http/handler.go
Normal file
@@ -0,0 +1,279 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.toowon.com/jimmy/go-common/middleware"
|
||||
)
|
||||
|
||||
// Handler HTTP处理器包装器,封装ResponseWriter和Request,提供简洁的API
|
||||
type Handler struct {
|
||||
w http.ResponseWriter
|
||||
r *http.Request
|
||||
}
|
||||
|
||||
// NewHandler 创建Handler实例
|
||||
func NewHandler(w http.ResponseWriter, r *http.Request) *Handler {
|
||||
return &Handler{
|
||||
w: w,
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
// ResponseWriter 获取原始的ResponseWriter(需要时使用)
|
||||
func (h *Handler) ResponseWriter() http.ResponseWriter {
|
||||
return h.w
|
||||
}
|
||||
|
||||
// Request 获取原始的Request(需要时使用)
|
||||
func (h *Handler) Request() *http.Request {
|
||||
return h.r
|
||||
}
|
||||
|
||||
// Context 获取请求的Context
|
||||
func (h *Handler) Context() context.Context {
|
||||
return h.r.Context()
|
||||
}
|
||||
|
||||
// ========== 响应方法(黑盒模式) ==========
|
||||
|
||||
// Success 成功响应
|
||||
// data: 响应数据,可以为nil
|
||||
func (h *Handler) Success(data interface{}) {
|
||||
writeJSON(h.w, http.StatusOK, 0, "success", data)
|
||||
}
|
||||
|
||||
// SuccessWithMessage 带消息的成功响应
|
||||
func (h *Handler) SuccessWithMessage(message string, data interface{}) {
|
||||
writeJSON(h.w, http.StatusOK, 0, message, data)
|
||||
}
|
||||
|
||||
// Error 错误响应
|
||||
// code: 业务错误码,非0表示业务错误
|
||||
// message: 错误消息
|
||||
func (h *Handler) Error(code int, message string) {
|
||||
writeJSON(h.w, http.StatusOK, code, message, nil)
|
||||
}
|
||||
|
||||
// SystemError 系统错误响应(返回HTTP 500)
|
||||
// message: 错误消息
|
||||
func (h *Handler) SystemError(message string) {
|
||||
writeJSON(h.w, http.StatusInternalServerError, 500, message, nil)
|
||||
}
|
||||
|
||||
// WriteJSON 写入JSON响应(自定义HTTP状态码和业务状态码)
|
||||
// httpCode: HTTP状态码(200表示正常,500表示系统错误等)
|
||||
// code: 业务状态码(0表示成功,非0表示业务错误)
|
||||
// message: 响应消息
|
||||
// data: 响应数据
|
||||
func (h *Handler) WriteJSON(httpCode, code int, message string, data interface{}) {
|
||||
writeJSON(h.w, httpCode, code, message, data)
|
||||
}
|
||||
|
||||
// SuccessPage 分页成功响应
|
||||
// list: 数据列表
|
||||
// total: 总记录数
|
||||
// page: 当前页码
|
||||
// pageSize: 每页大小
|
||||
// message: 响应消息(可选,如果为空则使用默认消息 "success")
|
||||
func (h *Handler) SuccessPage(list interface{}, total int64, page, pageSize int, message ...string) {
|
||||
msg := "success"
|
||||
if len(message) > 0 && message[0] != "" {
|
||||
msg = message[0]
|
||||
}
|
||||
|
||||
pageData := &PageData{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
writeJSON(h.w, http.StatusOK, 0, msg, pageData)
|
||||
}
|
||||
|
||||
// ========== 请求解析方法(黑盒模式) ==========
|
||||
|
||||
// ParseJSON 解析JSON请求体
|
||||
// v: 目标结构体指针
|
||||
func (h *Handler) ParseJSON(v interface{}) error {
|
||||
body, err := io.ReadAll(h.r.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer h.r.Body.Close()
|
||||
|
||||
if len(body) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return json.Unmarshal(body, v)
|
||||
}
|
||||
|
||||
// GetQuery 获取查询参数
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (h *Handler) GetQuery(key, defaultValue string) string {
|
||||
value := h.r.URL.Query().Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// GetQueryInt 获取整数查询参数
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (h *Handler) GetQueryInt(key string, defaultValue int) int {
|
||||
value := h.r.URL.Query().Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
intValue, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
// GetQueryInt64 获取int64查询参数
|
||||
func (h *Handler) GetQueryInt64(key string, defaultValue int64) int64 {
|
||||
value := h.r.URL.Query().Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
intValue, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
// GetQueryBool 获取布尔查询参数
|
||||
func (h *Handler) GetQueryBool(key string, defaultValue bool) bool {
|
||||
value := h.r.URL.Query().Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
boolValue, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return boolValue
|
||||
}
|
||||
|
||||
// GetQueryFloat64 获取float64查询参数
|
||||
func (h *Handler) GetQueryFloat64(key string, defaultValue float64) float64 {
|
||||
value := h.r.URL.Query().Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
floatValue, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return floatValue
|
||||
}
|
||||
|
||||
// GetFormValue 获取表单值
|
||||
func (h *Handler) GetFormValue(key, defaultValue string) string {
|
||||
value := h.r.FormValue(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// GetFormInt 获取表单整数
|
||||
func (h *Handler) GetFormInt(key string, defaultValue int) int {
|
||||
value := h.r.FormValue(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
intValue, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
// GetFormInt64 获取表单int64
|
||||
func (h *Handler) GetFormInt64(key string, defaultValue int64) int64 {
|
||||
value := h.r.FormValue(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
intValue, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
// GetFormBool 获取表单布尔值
|
||||
func (h *Handler) GetFormBool(key string, defaultValue bool) bool {
|
||||
value := h.r.FormValue(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
boolValue, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return boolValue
|
||||
}
|
||||
|
||||
// GetHeader 获取请求头
|
||||
func (h *Handler) GetHeader(key, defaultValue string) string {
|
||||
value := h.r.Header.Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// ParsePaginationRequest 从请求中解析分页参数
|
||||
// 支持从查询参数和form表单中解析
|
||||
// 优先级:查询参数 > form表单
|
||||
func (h *Handler) ParsePaginationRequest() *PaginationRequest {
|
||||
return ParsePaginationRequest(h.r)
|
||||
}
|
||||
|
||||
// GetTimezone 从请求的context中获取时区
|
||||
// 如果使用了middleware.Timezone中间件,可以从context中获取时区信息
|
||||
// 如果未设置,返回默认时区 AsiaShanghai
|
||||
func (h *Handler) GetTimezone() string {
|
||||
return middleware.GetTimezoneFromContext(h.r.Context())
|
||||
}
|
||||
|
||||
// HandleFunc 将Handler函数转换为标准的http.HandlerFunc
|
||||
// 这样可以将Handler函数直接用于http.HandleFunc
|
||||
// 示例:
|
||||
//
|
||||
// http.HandleFunc("/users", http.HandleFunc(func(h *http.Handler) {
|
||||
// h.Success(data)
|
||||
// }))
|
||||
func HandleFunc(fn func(*Handler)) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
h := NewHandler(w, r)
|
||||
fn(h)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user