android - 在(Android )中,如何动态设置标题

我使用一个使用授权方案的API,需要一个特殊的"x-authorization"头来对请求进行身份验证,例如,对于授权令牌为abc123的用户,此更新设置非常有效:


@Headers("X-Authorization: abc123")


@GET("/posts")


Observable<List<Post>> get_posts();



我缓存了用户令牌的X-Authorization,因此可以访问它,但是我不能将它放在@Headers声明中。


@Headers("X-Authorization:" + token)


@GET("/posts")


Observable<List<Post>> get_posts();



这里出现编译错误: Error:(41, 34) error: element value must be a constant expression

如何解决这个问题?

时间:

Since Retrofit 2.0你有两个选择

1)使用OkHttp 2.2 使用Interceptor

在Http级别,你有更多的控制权,所以,你可以将header只应用到特定端口的特定请求。


public class MyOkHttpInterceptor implements Interceptor {



@Override


public Response intercept(Chain chain) throws IOException {


 Request originalRequest = chain.request();


 if (!"/posts".contains(originalRequest.url()) ) {


 return chain.proceed(originalRequest);


 }



 String token = // get token logic 



 Request newRequest = originalRequest.newBuilder()


 .header("X-Authorization", token)


 .build();



 return chain.proceed(newRequest);


}



[...]



OkHttpClient okHttpClient = new OkHttpClient();


okHttpClient.networkInterceptors().add(new MyOkHttpInterceptor());


OkClient okClient = new OkClient(okHttpClient);


YourApi api = new RestAdapter.Builder()


 .setEndpoint(url)


 .setClient(okClient)


 .build()


 .create(YourApi.class);



文档


// Replaces the header with the the value of its target.


@GET("/")


void foo(@Header("Accept-Language") String lang, Callback<Response> cb);



头参数可能为空,这将从请求中省略它们,传递一个列表或数组将导致每个非null项的标题。

注意:标题不会互相覆盖,

3)RequestInterceptor

文档:在执行每个请求之前拦截每个请求以添加附加数据。

你可以这么做


public class MyRetrofitInterceptor implements RequestInterceptor {



@Override


public void intercept(RequestFacade req) {


 String token = // get token logic 


 if (token != null) {


 req.addHeader("X-Authorization", token);


 }


}



[...]



YourApi api = new RestAdapter.Builder()


 .setEndpoint(url)


 .setRequestInterceptor(new MyRetrofitInterceptor())


 .build()


 .create(YourApi.class);



此外,RequestFacade不会公开关于请求的许多信息,因此不会在它周围添加许多逻辑。

在参数中传递标头很有用,查看下面的代码:


 @GET("/posts")


Observable<JsonElement> getDataFromService(


 @HeaderMap Map<String, String> headers,


 @QueryMap HashMap<String, Object> queryParams


);



 hashMap1.put("Authorization", token);


 return ApiService.getAPI_test().getDataFromService(hashMap1, url, hashMap)


 .observeOn(AndroidSchedulers.mainThread())


 .subscribeOn(Schedulers.io());



...