Go如何重写http.Client所有响应的Content-Type响应头
问题
在Go语言中使用http.Client时,需要在响应被业务逻辑处理前,自动将所有响应的Content-Type统一修改为application/json,忽略响应原本的内容类型标注。
背景:对接的第三方API存在缺陷,接口实际返回JSON格式内容,但响应头的
Content-Type被错误设置为其他值,导致客户端解析异常。
原有示例代码:
... requestURL := fmt.Sprintf("http://localhost:%d", serverPort) req, err := http.NewRequest(http.MethodGet, requestURL, nil) if err != nil { fmt.Printf("client: could not create request: %s\n", err) os.Exit(1) } res, err := http.DefaultClient.Do(req) if err != nil { fmt.Printf("client: error making http request: %s\n", err) os.Exit(1) } fmt.Printf("client: got response!\n") fmt.Printf("client: status code: %d\n", res.StatusCode) resBody, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Printf("client: could not read response body: %s\n", err) os.Exit(1) } fmt.Printf("client: response body: %s\n", resBody) }
实现方案
http.Client没有提供直接修改响应头的现成配置属性,你需要自定义实现http.RoundTripper接口,包装默认的传输层,在响应返回业务逻辑前拦截修改头字段:
- 自定义结构体持有基础
RoundTripper实例,实现RoundTrip方法 - 在方法内调用基础传输层完成实际请求,拿到响应对象后直接覆写
Content-Type头 - 把自定义的传输层实例赋值给
http.Client的Transport字段即可全局生效
可直接复用的代码实现:
// 自定义传输层,强制覆写响应Content-Type type forceJsonTransport struct { Base http.RoundTripper } func (t *forceJsonTransport) RoundTrip(req *http.Request) (*http.Response, error) { base := t.Base if base == nil { base = http.DefaultTransport } // 执行实际HTTP请求 resp, err := base.RoundTrip(req) if err != nil { return nil, err } // 强制修改响应头 resp.Header.Set("Content-Type", "application/json") return resp, nil }
使用时替换原有默认客户端即可:
// 初始化带自定义传输层的客户端 client := &http.Client{ Transport: &forceJsonTransport{}, } // 后续所有请求用该client发起,响应头会被自动修改 res, err := client.Do(req)
该实现属于HTTP客户端的底层拦截逻辑,不会侵入原有业务的响应读取、解析流程,对该客户端发出的所有请求生效。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

