From a6e591d2ee7900e19de9f6a951e883c57abc36e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 13 Dec 2025 22:37:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8D=87=E7=BA=A7HTTP=E8=AF=B7?= =?UTF-8?q?=E6=B1=82,=20=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89messa?= =?UTF-8?q?ge=20location=20=E5=92=8C=20=E8=A7=A3=E6=9E=90=E6=95=B4?= =?UTF-8?q?=E4=B8=AA=E5=93=8D=E5=BA=94body?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httpclient/define/request.go | 44 +++++++++++++++++--------------- httpclient/implement/response.go | 29 ++++++++++++++++----- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/httpclient/define/request.go b/httpclient/define/request.go index 3361c15..639835a 100644 --- a/httpclient/define/request.go +++ b/httpclient/define/request.go @@ -9,6 +9,7 @@ package define import ( "context" + "go.uber.org/zap" ) @@ -18,27 +19,28 @@ import ( // // Date : 17:10 2024/5/24 type Request struct { - Ctx context.Context `json:"-"` // 请求上下文 - PathParam map[string]string `json:"path_param"` // 替换url中的占位符 - Body map[string]any `json:"body"` // 请求Body - Header map[string]any `json:"header"` // 请求Header - Cookie map[string]any `json:"cookie"` // 请求Cookie - Query map[string]any `json:"query"` // 请求query - Static map[string]map[string]any `json:"static"` // 静态参数: location => valName => val - FullUrl string `json:"full_url"` // 完整的请求URL - ContentType string `json:"content_type"` // 请求类型 - Method string `json:"method"` // 请求方法 - DataField string `json:"data_field"` // 数据字段 - CodeField string `json:"code_field"` // 业务状态码字段 - CodeLocation string `json:"code_location"` // 业务状态码位置 - MessageField string `json:"message_field"` // code描述字段 - DataReceiver any `json:"-"` // 响应data部分数据解析 - SuccessHttpCodeList []int `json:"success_http_code_list"` // 哪些http状态码视为成功, 不配置, 默认2xx - SuccessCodeList []string `json:"success_code_list"` // 哪些业务状态码视为成功 - ConnectTimeout int64 `json:"connect_timeout"` // 连接超时时间: ms - ReadTimeout int64 `json:"read_timeout"` // 读取超时时间 - RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则 - Logger *zap.Logger `json:"-"` // 日志记录器 + Ctx context.Context `json:"-"` // 请求上下文 + PathParam map[string]string `json:"path_param"` // 替换url中的占位符 + Body map[string]any `json:"body"` // 请求Body + Header map[string]any `json:"header"` // 请求Header + Cookie map[string]any `json:"cookie"` // 请求Cookie + Query map[string]any `json:"query"` // 请求query + Static map[string]map[string]any `json:"static"` // 静态参数: location => valName => val + FullUrl string `json:"full_url"` // 完整的请求URL + ContentType string `json:"content_type"` // 请求类型 + Method string `json:"method"` // 请求方法 + DataField string `json:"data_field"` // 数据字段,// 数据字段 BODY_ROOT 代表整个BODY 都是带解析数据 + CodeField string `json:"code_field"` // 业务状态码字段 + CodeLocation string `json:"code_location"` // 业务状态码位置 + MessageField string `json:"message_field"` // code描述字段 + MessageFieldLocation string `json:"message_field_location"` // code 描述字段位置 + DataReceiver any `json:"-"` // 响应data部分数据解析 + SuccessHttpCodeList []int `json:"success_http_code_list"` // 哪些http状态码视为成功, 不配置, 默认2xx + SuccessCodeList []string `json:"success_code_list"` // 哪些业务状态码视为成功 + ConnectTimeout int64 `json:"connect_timeout"` // 连接超时时间: ms + ReadTimeout int64 `json:"read_timeout"` // 读取超时时间 + RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则 + Logger *zap.Logger `json:"-"` // 日志记录器 } // RequestRetryRule 重试规则 diff --git a/httpclient/implement/response.go b/httpclient/implement/response.go index c2ed8ef..c0d88cb 100644 --- a/httpclient/implement/response.go +++ b/httpclient/implement/response.go @@ -10,12 +10,13 @@ package implement import ( "errors" "fmt" + "net/http" + "strings" + "git.zhangdeman.cn/zhangdeman/consts" "git.zhangdeman.cn/zhangdeman/network/httpclient/define" "git.zhangdeman.cn/zhangdeman/serialize" "github.com/tidwall/gjson" - "net/http" - "strings" ) // Response 响应结果解析 @@ -98,21 +99,35 @@ func (r *Response) fillResponseBody(reqCfg *define.Request, response *define.Res return errors.New("response body Marshal error :" + err.Error()) } response.Data = string(jsonByte) - if strings.ToLower(reqCfg.CodeLocation) == "header" { - if reqCfg.CodeField == "code" { + if strings.ToUpper(reqCfg.CodeLocation) == consts.ResponseDataLocationHeader.String() { + if reqCfg.CodeField == "" || reqCfg.CodeField == "code" { response.Code = fmt.Sprintf("%v", response.HttpCode) - response.Message = response.RestyResponse.Status() } else { response.Code = response.RestyResponse.Header().Get(reqCfg.CodeField) - response.Message = response.RestyResponse.Header().Get(reqCfg.MessageField) } } else { // 统一认为Body response.Code = gjson.Get(response.Data, reqCfg.CodeField).String() + } + + if reqCfg.MessageFieldLocation == "" { + reqCfg.MessageFieldLocation = reqCfg.CodeLocation + } + + if strings.ToUpper(reqCfg.MessageFieldLocation) == consts.ResponseDataLocationBody.String() { + // header, 统一使用 http status + response.Message = response.RestyResponse.Status() + } else { response.Message = gjson.Get(response.Data, reqCfg.MessageField).String() } - businessData := gjson.Get(response.Data, reqCfg.DataField) + var businessData gjson.Result + if reqCfg.DataField == "" || reqCfg.DataField == consts.ResponseDataLocationBodyRoot.String() { + // 整个Body都是数据 + businessData = gjson.Parse(response.Data) + } else { + businessData = gjson.Get(response.Data, reqCfg.DataField) + } if businessData.Value() == nil { // data为空指针, 归一化成空对象 response.Body = map[string]any{}