[java] Android Retrofit 매개 변수화 된 @Headers

OAuth를 사용하고 있으며 요청할 때마다 헤더에 OAuth 토큰을 넣어야합니다. 내가 볼 @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
)



답변

@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 : Retrofit2를 사용 Interceptor하는 경우 대신 사용해야 합니다.RequestInterceptor

RequestInterceptorRetrofit 2.0에서 더 이상 사용할 수 없기 때문에


답변

예, 런타임에 전달할 수 있습니다. 사실 입력 한 것과 거의 동일합니다. 이것은 SecretApiInterface.java 라는 이름의 API 인터페이스 클래스에 있습니다.

public interface SecretApiInterface {

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

}

그런 다음 요청에서이 인터페이스로 매개 변수를 전달합니다. 다음 행을 따라 전달합니다. (이 파일은 예를 들어 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());
    }
}

경우 Somehow.Magically.getToken(), 그것은 당신이 어떻게 당신이 그것을 정의에 토큰을 반환하는 메서드 호출까지입니다.

물론 @Header("Blah") String blah귀하의 경우와 같이 인터페이스 구현에 하나 이상의 주석을 가질 수 있습니다 !

나는 그것도 혼란스럽고 문서 는 그것이 헤더를 대체 한다고 분명히 말하고 있지만 그렇지 않습니다 !
실제로 @Headers("hardcoded_string_of_liited_use")주석 과 같이 추가됩니다.

도움이 되었기를 바랍니다 😉


답변

허용되는 대답은 이전 버전의 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();

누군가에게 도움이되기를 바랍니다. 🙂


답변

개조 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에 연결하는 데 사용하고 있습니다.


답변