如何动态设置API请求头user-type或修改Java的final变量?
解决Retrofit动态切换user-type请求头的问题
咱先搞清楚为啥你原来的方法行不通:
- Java里被
public static final修饰的变量,一旦初始化完成就绝对不能被重新赋值;再加上String是不可变类型,USERTYPE.replace("customer","guest")只会返回一个新的字符串,原变量的值根本没变;直接写USERTYPE=user更是连编译都过不了,编译器会直接阻止你修改final变量。 - 另外Retrofit的
@Headers注解只能接收编译期常量,就算你能改final变量的值,这个注解也不会感知到变化——因为它的值在编译时就已经固定了。
下面给你两个靠谱的解决方案,按需选择:
方案1:用@Header注解动态传值(推荐)
直接修改你的Retrofit接口方法,把user-type作为参数传入:
Call<ReturnPojo> addpost(@Url String s, @Header("user-type") String userType, @Body Add body);
之后调用接口的时候,直接传对应的"customer"或者"guest"就行:
// 原来的customer场景 api.addpost(url, "customer", body).enqueue(...); // 需要切换成guest时 api.addpost(url, "guest", body).enqueue(...);
这种方式最直观,完全符合Retrofit的设计规范,代码可读性也高。
方案2:用OkHttp Interceptor全局动态设置请求头
如果你的很多接口都需要这个user-type头,不想每个方法都加参数,可以用Interceptor来全局管理:
- 先写一个自定义的Interceptor:
public class UserTypeInterceptor implements Interceptor { private volatile String userType; // 用volatile保证多线程下的可见性 public UserTypeInterceptor(String initialUserType) { this.userType = initialUserType; } // 提供方法来切换userType public void setUserType(String newUserType) { this.userType = newUserType; } @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); // 给请求添加/替换user-type头 Request modifiedRequest = originalRequest.newBuilder() .header("user-type", userType) .build(); return chain.proceed(modifiedRequest); } }
- 构建Retrofit的时候把这个Interceptor加到OkHttpClient里:
// 初始化时设置默认的userType为customer UserTypeInterceptor userTypeInterceptor = new UserTypeInterceptor("customer"); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(userTypeInterceptor) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的基础URL") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build();
- 需要切换成guest时,直接调用:
userTypeInterceptor.setUserType("guest");
之后所有通过这个Retrofit实例发起的请求,都会自动带上最新的user-type头。
内容的提问来源于stack exchange,提问作者Subin Babu
相关产品推荐
相关产品推荐

