当前位置: 首页 > 知识库问答 >
问题:

如何在改造(Android)中动态设置标头

伊羽
2023-03-14

我使用的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)错误:元素值必须是常量表达式

有什么办法可以绕过这个吗?

共有3个答案

傅博容
2023-03-14

改装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。您可以用任何需要通过的东西替换,也可以将其删除。

巢德华
2023-03-14

参数中传递标头会很有帮助。查看以下代码;

 @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
);
周良弼
2023-03-14

自改型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