我使用的API使用授权方案,该方案需要设置特殊的“X-Authoration”标头来验证请求。例如,此Retrofit设置非常适合身份验证令牌为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();
我在这里得到一个编译错误:错误:(41,34)错误:元素值必须是常量表达式
有什么办法可以绕过这个吗?
改装2中的动态割台
我在改造2中添加动态标题太费劲了。
我浏览了很多博客和StackOver flow。每个人都展示了拦截器的例子。
这并不是一件明智的事情,仅仅为了一个API调用,我们需要做很多工作。
你只需要添加@HeaderMap作为有趣的参数。我用非常简单的方式做到了:-
静态编程语言
val headers = HashMap<String, String>()
headers["KEY_AUTHORIZATION"] = "paste AUTHORIZATION value here"
headers["KEY_TOKEN"] = "paste TOKEN value here"
val jsonObject= JsonObject()
I am passing here header and other data also
Calling of fun:-
postEvent(headers,jsonObject)
API Declaration
@POST("/v1/post_data")
fun postEvent(@HeaderMap headers: Map<String, String>, @Body jsonObject: JsonObject): Call<JsonObject>
API Declaration with RxAndroid
@POST("/v1/post_data")
fun postEvent(@HeaderMap headers: Map<String, String>, @Body jsonObject: JsonObject): Single<JsonObject>
第二个参数在这里我有JsonObject。您可以用任何需要通过的东西替换,也可以将其删除。
在Java中
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("KEY_AUTHORIZATION","paste AUTHORIZATION value here");
headers.put("KEY_TOKEN", "paste TOKEN value here");
JsonObject jsonObject= new JsonObject();
I am passing here header and other data also
Calling of fun:-
postEvent(headers,jsonObject);
API Declaration
@POST("/v1/post_data")
Call<JsonObject> postEvent(@HeaderMap Map<String, String> headers, @Body JsonObject jsonObject);
API Declaration with RxAndroid
@POST("/v1/post_data")
Single<JsonObject> postEvent(@HeaderMap Map<String, String> headers, @Body JsonObject jsonObject);
第二个参数在这里我有JsonObject。您可以用任何需要通过的东西替换,也可以将其删除。
在参数中传递标头会很有帮助。查看以下代码;
@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());
更新:
越多越好
@GET("/posts")
Observable<JsonElement> getDataFromService(
@Header("Authorization") token: String = "Bearer " + PreferenceUtils.getToken(),
@QueryMap HashMap<String, Object> queryParams
);
自改型2.0以来,您有两种选择:
1)使用OkHttp 2.2使用拦截器
在Http级别,您可以对请求进行更多的控制,因此您可以只对特定endpoint的特定请求应用头,等等。
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);
编辑:添加@JakeWarthon评论作为另一个选项也是有效的。
2) 将@Header放在方法参数上,并在调用时将其作为值传递。
来自文档:
// Replaces the header with the the value of its target.
@GET("/")
void foo(@Header("Accept-Language") String lang, Callback<Response> cb);
标头参数可能为空,这将从请求中省略它们。传递列表或数组将导致每个非空项的标头。
注意:标头不会相互覆盖。所有同名的标头都将包含在请求中。
编辑:此选项不应被视为改造 2.* 放弃了对拦截器的支持。
<罢工> 3)用户改造Request estInterceptor
来自文档:在执行每个请求之前拦截它,以便添加其他数据。
你可以做这样的事情
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);
这种方法的“问题”在于,拦截器将在所有endpoint上执行,因为它是在RestaAdapter级别设置的,而不是每个endpoint。此外,RequestFacade
没有公开关于请求的很多信息,因此没有机会在其周围添加很多逻辑。
我使用@FormUrlEncoded发送到服务器。当我向服务器发送字符串时,我得到如下请求体 所以我找到了加法器。拦截器 ApiInterface接口 但它不起作用。英语和数字都可以,但不是我的语言。如何修复它?我也试过设置-
我正在drawable文件夹中存储与项目相关的图像。我还将图像名称存储在字符串变量中,并尝试动态地将这些图像设置为imageview。但是图像没有显示出来。请在这方面帮助我。 我的代码: 在上面的代码中,“图像名称”是包含图像名称的字符串变量。 提前谢谢
问题内容: 我想将String放入比给定单元格宽度更长的字符串中。如何动态设置,以便可以读取整个String?这是一个例子: 在这里,您将看到将给定单元格较长的每个文本换行的代码 谢谢,但是我想根据字符串的长度动态地实现RowHeight。我想读取单元格中的整个字符串/文本。有什么建议? 我是Java初学者,这是我的第一个问题。我很高兴得到答案。 问题答案: 使用JTextArea作为呈现组件时会
我想做的是根据滚动的数字将Imageview设置为不同的骰子侧。
我是android编程的新手。我想在显示时在一个xml中动态设置图像。具体来说,我将项目相关的图像存储在drawable文件夹中。此外,我将图像名称存储在字符串变量中,并尝试动态地将这些图像设置为imageview。但图像没有显示。 我的代码:
问题内容: 在上述情况下,bean中的属性随环境而变化。在开发时,config的引用更改为。并在阶段中将参考更改为。问题在检入spring文件时出现。每次签入之前,我们都必须分析config的引用。如果config的引用具有签入的值,我们可能必须解释很多问题。 有什么解决方案可以使其自动化? 注意:春季版本为2.0.1 问题答案: 使用Spring的PropertyPlaceholderConfi