Java Android Retrofit 参数化@Headers

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18478258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:59:09  来源:igfitidea点击:

Android Retrofit Parameterized @Headers

javaandroidannotationsretrofit

提问by jpotts18

I am using OAuth and I need to put the OAuth token in my header every time I make a request. I see the @Headerannotation, but is there a way to make it parameterized so i can pass in at run time?

我正在使用 OAuth,每次发出请求时都需要将 OAuth 令牌放在我的标头中。我看到了@Header注释,但是有没有办法让它参数化,这样我就可以在运行时传入?

Here is the concept

这是概念

@Header({Authorization:'OAuth {var}', api_version={var} })

@Header({Authorization:'OAuth {var}', api_version={var} })

Can you pass them in at Runtime?

你能在运行时传递它们吗?

@GET("/users")
void getUsers(
    @Header("Authorization") String auth, 
    @Header("X-Api-Version") String version, 
    Callback<User> callback
)

采纳答案by Felix

Besides using @Header parameter, I'd rather use RequestInterceptor to update all your request without changing your interface. Using something like:

除了使用@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 : If you are using Retrofit2, you should use Interceptorinstead of RequestInterceptor

p/s :如果您使用的是 Retrofit2,则应使用Interceptor而不是RequestInterceptor

Since RequestInterceptoris not longer available in Retrofit 2.0

由于RequestInterceptor在 Retrofit 2.0 中不再可用

回答by nana

Yes, you can pass them in runtime. As a matter of fact, pretty much exactly as you typed it out. This would be in your API interface class, named say SecretApiInterface.java

是的,您可以在运行时传递它们。事实上,几乎和你打出来的一模一样。这将在您的 API 接口类中,命名为SecretApiInterface.java

public interface SecretApiInterface {

    @GET("/secret_things")
    SecretThing.List getSecretThings(@Header("Authorization") String token)

}

Then you pass the parameters to this interface from your request, something along those lines: (this file would be for example SecretThingRequest.java)

然后你将参数从你的请求传递给这个接口,沿着这些行:(这个文件将是例如SecretThingRequest.java

public class SecretThingRequest extends RetrofitSpiceRequest<SecretThing.List, SecretApiInteface>{

    private String token;

    public SecretThingRequest(String token) {
        super(SecretThing.List.class, SecretApiInterface.class);
        this.token = token;
    }

    @Override
    public SecretThing.List loadDataFromNetwork() {
        SecretApiInterface service = getService();
        return service.getSecretThings(Somehow.Magically.getToken());
    }
}

Where Somehow.Magically.getToken()is a method call that returns a token, it is up to you where and how you define it.

Somehow.Magically.getToken()返回令牌的方法调用在哪里,取决于您定义它的位置和方式。

You can of course have more than one @Header("Blah") String blahannotations in the interface implementation, as in your case!

您当然可以@Header("Blah") String blah在接口实现中有多个注释,就像您的情况一样!

I found it confusing too, the documentationclearly says it replacesthe header, but it DOESN'T!
It is in fact added as with @Headers("hardcoded_string_of_liited_use")annotation

我也发现它很混乱,文档清楚地说它替换了标题,但它没有
它实际上是与@Headers("hardcoded_string_of_liited_use")注释一起添加的

Hope this helps ;)

希望这可以帮助 ;)

回答by pablisco

The accepted answer is for an older version of Retrofit. For future viewers the way to do this with Retrofit2.0 is using a custom OkHttp client:

接受的答案适用于旧版本的 Retrofit。对于未来的观众,使用Retrofit2.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();

Hope it helps someone. :)

希望它可以帮助某人。:)

回答by Soon Santos

Retrofit 2.3.0

改造 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();

I am using this to connect to GitHub.

我正在使用它连接到 GitHub。