Java Android改型参数化@Headers
我正在使用OAuth,每次发出请求时,我都需要将OAuth令牌放在我的头中。我看到了Java Android改型参数化@Headers,java,android,annotations,retrofit,Java,Android,Annotations,Retrofit,我正在使用OAuth,每次发出请求时,我都需要将OAuth令牌放在我的头中。我看到了@Header注释,但有没有办法将其参数化,以便在运行时传入 这是一个概念 @Header({Authorization:'OAuth{var}',api_version={var}}) 你能在运行时传递它们吗 @GET("/users") void getUsers( @Header("Authorization") String auth, @Header("X-Api-Version")
@Header
注释,但有没有办法将其参数化,以便在运行时传入
这是一个概念
@Header({Authorization:'OAuth{var}',api_version={var}})
你能在运行时传递它们吗
@GET("/users")
void getUsers(
@Header("Authorization") String auth,
@Header("X-Api-Version") String version,
Callback<User> callback
)
@GET(“/users”)
无效getUsers(
@标题(“授权”)字符串身份验证,
@标题(“X-Api-Version”)字符串版本,
回调
)
是的,您可以在运行时传递它们。事实上,和你打出来的差不多。这将在API接口类中,名为saySecretApiInterface.java
public interface SecretApiInterface {
@GET("/secret_things")
SecretThing.List getSecretThings(@Header("Authorization") String token)
}
然后,您将请求中的参数传递到此接口,大致如下:(该文件将是例如SecretThingRequest.java)
public类SecretThingRequest扩展了该请求{
私有字符串令牌;
公共加密请求(字符串令牌){
super(SecretThing.List.class、SecretApiInterface.class);
this.token=token;
}
@凌驾
public SecretThing.List loadDataFromNetwork(){
secretapipinterface service=getService();
return service.getSecretThings(莫名其妙地.Magically.getToken());
}
}
其中以某种方式.Magically.getToken()
是一个返回令牌的方法调用,它取决于您在何处以及如何定义它
当然,在接口实现中可以有多个@Header(“Blah”)字符串Blah
注释,就像您的例子一样强>
我发现它也让人困惑,清楚地说它取代了标题,但它没有事实上,它是与
@头一起添加的(“硬编码字符串”的使用”)
注释
希望这有帮助;) 除了使用@Header参数外,我更愿意使用RequestInterceptor更新所有请求,而不更改接口。使用类似于:
RestAdapter.Builder builder = new RestAdapter.Builder()
.setRequestInterceptor(new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json;versions=1");
if (isUserLoggedIn()) {
request.addHeader("Authorization", getToken());
}
}
});
p/s:如果您使用的是Reformation2,您应该使用拦截器
而不是请求拦截器
由于
RequestInterceptor
在改型2.0中不再可用,因此公认的答案是旧版本的改型。对于未来的观众,使用改造2.0实现这一点的方法是使用自定义OkHttp客户端:
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Builder ongoing = chain.request().newBuilder();
ongoing.addHeader("Accept", "application/json;versions=1");
if (isUserLoggedIn()) {
ongoing.addHeader("Authorization", getToken());
}
return chain.proceed(ongoing.build());
}
})
.build();
Retrofit retrofit = new Retrofit.Builder()
// ... extra config
.client(httpClient)
.build();
希望它能帮助别人。:) 改装2.3.0
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", accessToken);
return chain.proceed(newRequest.build());
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(GithubService.BASE_URL)
.client(okHttpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
我正在使用它连接到GitHub。你知道这一点吗?我需要在标题中传递一个令牌,我也在寻找解决方案,从文档中可以看出,方法上的注释将字段逐个添加到标题中,但只支持文本。参数注释将标题替换为提供的值。此处相同,在使用改型时无法找到如何处理会话。我们不需要传递所有项,改型本身处理所有项。请在StackOverflow中检查我的答案。这没有直接关系,但如果您发现需要从请求对象获取值以生成授权标头,则需要扩展ApacheClient并重复执行请求对象(列表标头=…;请求requestNew=新请求(request.getMethod(),request.getUrl(),headers,request.getBody();request=requestNew)。这是一个弄乱编码的技巧,最好使用@nana的答案RestAdapter
取决于改型1,在改型2中是改型
。我将使用Refught2,所以如果像上面的代码那样使用RequestInterceptor
,就不会有问题了?我在文档中发现它不会替换现有的头:“注意,头不会相互覆盖。”检查和“头操纵”在dagger2的常见用法中,Refught2将是单例的,因此不会每次都创建httpclient。在这种情况下,isUserLoggedIn()没有意义,对吗?目前我能看到的唯一解决方案是,当用户登录状态更改时,强制重新初始化Reformation2,以便在请求中添加或删除相应的头。。还是有一些我目前看不到的显而易见的解决方案?谢谢。@bajicdusko这是我完全一样的connundrum。你找到解决办法了吗?以前的版本效率更高,这似乎太浪费了,也很奇怪。@deed02392您可以设置一个复合的拦截器
,您可以在以后的阶段设置或重置拦截器。然而,我认为作为一个单身者进行改造可能是早期优化的标志。创建一个新的改造实例并没有任何开销:我并没有真正深入地考虑它。我有一些ApiFactory类,它也是用dagger2初始化的,它负责更新的初始化。我在ApiFactory中公开了一个公共方法,它在需要时强制重新初始化改造实例,所以它非常简单。我可能做错了,但它完成了任务,我只将其用于授权标题,以便在用户登录或注销时使用。另一个选择是在端点定义中使用@Header注释,这对我来说是不可接受的。我应该在每个端点上设置它,这是不实际的。@pablisco啊,据我所知,一旦创建了一个实例,就不能添加或删除拦截器。
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", accessToken);
return chain.proceed(newRequest.build());
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(GithubService.BASE_URL)
.client(okHttpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.build();