Retrofit拦截器静态Header与接口动态Header共存缺失问题咨询
问题根因
- 核心问题出在拦截器的
intercept方法里使用了.headers(defaultHeader().build()):Retrofit的Request.Builder.headers()方法会直接替换当前请求已有的全部请求头,你通过@Header注解添加的动态请求头是提前附加到原始请求上的,这一步直接把所有动态头全部覆盖清空,只剩你生成的静态头。 - 额外问题:你实现的
addHeader方法存在逻辑错误,每次调用defaultHeader()都会生成全新的Headers.Builder实例,你往第一个实例添加键值对后又返回了新创建的defaultHeader()实例,添加的自定义头会直接丢失,该方法完全不生效。
修复方案
1. 修正拦截器的头添加逻辑
不要直接替换全部头,改为遍历静态头列表,如果原始请求不存在该头则添加,既避免覆盖已经存在的动态头,也能保证静态头作为默认值生效:
@NotNull @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request.Builder requestBuilder = originalRequest.newBuilder(); // 仅当原始请求没有对应头时才添加静态默认头,不覆盖动态传入的头 Headers defaultHeaders = defaultHeader().build(); for (int i = 0; i < defaultHeaders.size(); i++) { String key = defaultHeaders.name(i); String value = defaultHeaders.value(i); if (originalRequest.header(key) == null) { requestBuilder.addHeader(key, value); } } // 添加authtoken,同样优先保留手动传入的authtoken if (this.authtoken != null && originalRequest.header("authtoken") == null) { requestBuilder.addHeader("authtoken", this.authtoken); } return chain.proceed(requestBuilder.build()); }
2. 修正addHeader方法逻辑(如果需要外部手动添加全局自定义头)
// 维护全局自定义头存储集合 private final Map<String, String> extraHeaders = new HashMap<>(); public void addHeader(@NotNull String key, @NotNull String value) { extraHeaders.put(key, value); } // defaultHeader方法追加自定义头 private Headers.Builder defaultHeader() { final String xUserAgent = Util.SDK_NAME + "/" + Util.SDK_VERSION; Headers.Builder builder = new Headers.Builder() .add("X-User-Agent", xUserAgent) .add("User-Agent", Util.defaultUserAgent()) .add("Content-Type", "application/json"); // 追加外部添加的全局自定义头 for (Map.Entry<String, String> entry : extraHeaders.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } return builder; }
内容的提问来源于stack exchange,提问作者Shailesh Mishra
相关产品推荐
相关产品推荐

