gpt4 book ai didi

java - Retrofit 2 - 在 api 级别添加 header 的优雅方式

转载 作者:太空狗 更新时间:2023-10-29 23:01:57 24 4
gpt4 key购买 nike

我的 Retrofit 2(当前为 2.0.2)客户端需要向请求添加自定义 header 。

我正在使用 Interceptor 将这些 header 添加到所有请求中:

OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
final Request request = chain.request().newBuilder()
.addHeader("CUSTOM_HEADER_NAME_1", "CUSTOM_HEADER_VALUE_1")
.addHeader("CUSTOM_HEADER_NAME_2", "CUSTOM_HEADER_VALUE_2")
...
.addHeader("CUSTOM_HEADER_NAME_N", "CUSTOM_HEADER_VALUE_N")
.build();

return chain.proceed(request);
}
});


Retrofit retrofitClient = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(httpClient)
.build();

有些 header 我一直想添加,但有些 header 我只需要根据特定端点的要求添加,例如用户是否需要进行身份验证。

我希望能够在 api 级别控制它,例如使用注释,例如:

public interface MyApi {
@NO_AUTH
@POST("register")
Call<RegisterResponse> register(@Body RegisterRequest data);

@GET("user/{userId}")
Call<GetUserResponse> getUser(@Path("userId") String userId);
}

当向register 发送请求时,无需添加身份验证 token ,但缺少@NO_AUTH 注释的请求将具有 token header 。

据我了解,Retrofit 2 不支持自定义注释,虽然我发现了 Custom Annotations with Retrofit 2 的解决方法,好像有点过分了。

我想避免在每个请求中传递这些 header ,例如:

public interface MyApi {
@POST("register")
Call<RegisterResponse> register(@Body RegisterRequest data);

@GET("user/{userId}")
Call<GetUserResponse> getUser(@Header("AuthToken") String token, @Path("userId") String userId);
}

每次我调用该方法而不是在拦截器中执行它时感觉是多余的(因为我可以静态访问 header 值)。
我只是需要在我的 Interceptor.intercept 实现中知道这个特定的请求是否应该有一个特定的 header 。

知道如何让这项工作成功吗?
我更喜欢通用解决方案,而不仅仅是针对身份验证 token 的情况,但也欢迎使用特定的解决方案。谢谢

最佳答案

我想出了一个非常简单而优雅(在我看来)的解决方案来解决我的问题,并且可能适用于其他场景。

我使用 Headers 注释来传递我的自定义注释,并且由于 OkHttp 要求它们遵循 Name: Value 格式,我决定我的格式为:@:ANNOTATION_NAME

所以基本上:

public interface MyApi {
@POST("register")
@HEADERS("@: NoAuth")
Call<RegisterResponse> register(@Body RegisterRequest data);

@GET("user/{userId}")
Call<GetUserResponse> getUser(@Path("userId") String userId);
}

然后我可以拦截请求,检查我是否有名称为@ 的注解。如果是这样,我获取该值并从请求中删除 header 。
即使您想拥有多个“自定义注释”,这也能很好地工作:

@HEADERS({
"@: NoAuth",
"@: LogResponseCode"
})

以下是提取所有这些“自定义注释”并将它们从请求中删除的方法:

new OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();

List<String> customAnnotations = request.headers().values("@");

// do something with the "custom annotations"

request = request.newBuilder().removeHeader("@").build();
return chain.proceed(request);
}
});

关于java - Retrofit 2 - 在 api 级别添加 header 的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37757520/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com