如何在Retrofit(Android)中动态设置标题

2024-05-26

我使用的 API 使用授权方案,需要设置特殊的“X-Authorization”标头来验证请求。例如,此 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();

我在这里得到一个编译错误:Error:(41, 34) error: element value must be a constant expression

关于如何解决这个问题有什么想法吗?


自 Retrofit 2.0 以来,您有两种选择


1)使用OkHttp 2.2+使用拦截器 https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Interceptor.kt

在 Http 级别,您可以更好地控制请求,因此您可以执行诸如仅将标头应用于向特定端点发出的特定请求等操作。

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);

Edit: 添加@杰克沃森 https://stackoverflow.com/users/132047/jake-wharton评论作为另一个选项也是有效的。

2) Put @Header http://square.github.io/retrofit/2.x/retrofit/retrofit2/http/Header.html方法参数上并在调用时将其作为值传递。

来自docs http://square.github.io/retrofit/2.x/retrofit/retrofit2/http/Header.html:

// Replaces the header with the the value of its target.
@GET("/")
void foo(@Header("Accept-Language") String lang, Callback<Response> cb);

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

注意:标头不会相互覆盖。所有具有相同名称的标头都将包含在请求中。


EDIT:此选项不应被视为 Retrofit 2.* 放弃了对拦截器的支持。

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);

这种方法的“问题”是拦截器将在所有端点上执行,因为它是在 RestAdapter 级别设置的,而不是每个端点。另外,RequestFacade不会公开有关请求的太多信息,因此没有机会围绕它添加太多逻辑。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Retrofit(Android)中动态设置标题 的相关文章

  • 找不到参数的方法 dependencyResolutionManagement()

    我正在尝试使用老师给我的一个项目 但它显示了一个错误 Settings file Users admin AndroidStudioProjects HTTPNetworking settings gradle line 1 A probl
  • 如何清除所有WebView存储的信息?

    我有一个 Android 浏览器 我可以选择清除缓存 存储 cookie 等 代码如下所示 webView clearCache true webView clearFormData webView clearHistory webView
  • 如何对这个字符串进行子串化

    我想得到这个字符串的 4 个部分 String string 10 trillion 896 billion 45 million 56873 我需要的4个部分是 10万亿 8960亿 4500万 和 56873 我所做的是删除所有空格 然
  • 在 Android Studio 中,为什么我必须在模拟器中单击“运行应用程序”两次才能启动应用程序?

    在 Android Studio 中 当我按播放按钮在 Android 模拟器上安装并运行应用程序时 大约 5 10 秒后 我在屏幕底部收到一条消息 显示 安装成功 但应用程序实际上并未运行在模拟器上 我必须再次按下播放按钮 这是非常令人沮
  • Android - 从资产中解析巨大(超大)JSON 文件的最佳方法

    我正在尝试从资产文件夹中解析一些巨大的 JSON 文件 我如何加载并添加到 RecyclerView 我想知道解析这种大文件 大约 6MB 的最佳方法是什么 以及您是否知道可以帮助我处理此文件的良好 API 我建议您使用GSON lib h
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • Android 后退按钮无法与 Flutter 选项卡内的导航器配合使用

    我需要在每个选项卡内有一个导航器 因此当我推送新的小部件时 选项卡栏会保留在屏幕上 代码运行得很好 但是 android 后退按钮正在关闭应用程序而不是运行 Navigator pop import package flutter mate
  • 是否可以将数组或对象添加到 Android 上的 SharedPreferences

    我有一个ArrayList具有名称和图标指针的对象 我想将其保存在SharedPreferences 我能怎么做 注意 我不想使用数据库 无论 API 级别如何 请检查SharedPreferences 中的字符串数组和对象数组 http
  • 计数物体和更好的填充孔的方法

    我是 OpenCV 新手 正在尝试计算物体的数量在图像中 我在使用 MATLAB 图像处理工具箱之前已经完成了此操作 并在 OpenCV Android 中也采用了相同的方法 第一步是将图像转换为灰度 然后对其进行阈值计算 然后计算斑点的数
  • Android Activity 生命周期函数基础知识

    我正在测试这段代码 它显示活动所处的状态 public class Activity101Activity extends Activity String tag Lifecycle Called when the activity is
  • 是否必须删除 Intent extra?

    这可能是一个愚蠢的问题 但是是否有一条规则规定消费活动必须显式删除 Intent 额外内容 或者只有在回收 Intent 对象时才如此 换句话说 如果我总是通过执行以下操作来链接到下一个活动 Intent i new Intent MyCu
  • 如何使用 Cordova 获取当前安装的应用程序的版本?

    我已经找到了应用程序可用性插件 https github com ohh2ahh AppAvailability它主要检查用户是否在其设备上安装了某个应用程序 是否有可能获得应用程序的当前版本 开发者名称 重要 以及所有可能的信息 一般来说
  • 在gradle插件中获取应用程序变体的包名称

    我正在构建一个 gradle 插件 为每个应用程序变体添加一个新任务 此新任务需要应用程序变体的包名称 这是我当前的代码 它停止使用最新版本的 android gradle 插件 private String getPackageName
  • 如何发布Android .aar源以使Android Studio自动找到它们?

    我正在将库发布到内部 Sonatype Nexus 存储库 Android Studio 有一个功能 可以自动查找通过 gradle 引用的库的正确源 我将 aar 的源代码作为单独的 jar 发布到 Nexus 但 Android Stu
  • 尝试在 ubuntu 中编译 android 内核时出错

    我正在尝试从源代码编译 Android 内核 并且我已经下载了所有正确的软件包来执行此操作 但由于某种原因我收到此错误 arm linux androideabi gcc error unrecognized command line op
  • 在activity_main.xml中注释

    我是安卓新手 据我所知 XML 中的注释与 HTML 中的注释相同 使用 形式 我想在 Android 项目的 Activity main xml 配置文件中写一些注释 但它给了我错误 值得注意的是 我使用的是 Eclipse 但目前 我直
  • 实现滚动选择 ListView 中的项目

    我想使用 ListView 您可以在其中滚动列表来选择一个项目 它应该像一个 Seekbar 但拇指应该是固定的 并且您必须使用该栏来调整它 我面临的一个问题是 我不知道这种小部件是如何调用的 这使得我很难搜索 所以我制作了下面这张图片 以
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 如何将 google+ 登录集成到我的 Android 应用程序中?

    大家好 实际上我需要通过我的应用程序从 google 登录人们 现在我阅读了 google 上的文档 其中指出 要允许用户登录 请将 Google Sign In 集成到您的应用中 初始化 GoogleApiClient 对象时 请求 PL
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • SET label : 将标签名称作为参数传递

    我有一个这样的查询 将 data 展开为行 MERGE p Book guid row bookGuid set p name row name p Science 我想传递标签 科学 作为参数 因为该标签对于我在 data 中传递的所有行
  • Laravel - LIKE 运算符来搜索加密值

    我正在尝试在 Laravel 应用程序中实现一个搜索模块 可以按名称过滤用户 为了保护用户 name 列行在数据库上加密 我面临的问题是下面的查询总是返回 0 结果 我在搜索数据库之前对搜索输入值进行加密 patients DB selec
  • 在 EB 上的 Docker 中运行的应用程序拒绝连接到自身

    我有一个 Play 2 Web 应用程序 我使用 Docker 将其部署到 Elastic Beanstalk 在此 Web 应用程序中 我启动了一个 Akka 集群 启动过程涉及将自动伸缩组中的所有节点添加为种子节点 包括其自身 第一次部
  • SVG SMIL animateTransform 缓动

    我正在尝试向简单的 SVG SMIL 动画添加计时功能 显然 计时 缓动可以通过以下方式设置keySplines属性 但是在我的示例中它不起作用
  • aerospike 连接超时工作不正常?

    我正在使用 aerospike java 客户端 v 6 0 1 并使用客户端读取策略中的以下配置 clientPolicy readPolicyDefault connectTimeout 1000 clientPolicy readPo
  • jQuery - 禁用选定的选项

    需要使用 jQuery 禁用选择框中已选择的选项 我希望它变灰 就像汇编选择 http www ryancramer com projects asmselect examples example1 html 测试我的例子here http
  • md5 哈希冲突。

    如果从 1 数到 X 其中 X 是第一个与前一个数字发生 md5 冲突的数字 那么 X 是哪个数字 我想知道如果我使用 md5 作为序列号 在发生冲突之前我可以期望能够枚举多少个单元 Theoretically you can expect
  • Yii 2.0 AJAX 请求的 CSRF 验证

    我有一个ajax触发从我的数据库中删除条目的函数 我需要去做CSRF验证相同 我怎样才能做到这一点 我正在发送CSRF cookie连同我的帖子请求 但是Yii 2 0不验证它 并且通过 ajax 传递的任何输入都会到达服务器 我该怎么做C
  • 如何在 Angular 5 中添加规范链接

    如何在 Angular 5 中动态添加规范链接 面对同样的问题 我四处搜索并找到了有关如何执行此操作的指南 https www concretepage com angular angular title service and canon
  • 如何获取另一个应用程序的版本名称

    我想获取 Minecraft Pocket Edition 的版本名称 示例 0 13 0 b5 这是MCPE 我的世界袖珍版 的包 com mojang minecraftpe 我想要版本为String 我怎样才能做到这一点 我的获取包名
  • Sqoop 导出分区的 Hive 表

    我在尝试导出分区的 Hive 表时遇到了一些问题 这是否完全受支持 我尝试用谷歌搜索并找到一张 JIRA 票证 sqoop export connect jdbc mysql localhost testdb table sales exp
  • Lucene 4.4.0新增ControlledRealTimeReopenThread示例使用

    在新的 Lucene 4 4 0 版本中 近实时管理器 org apache lucene search NRTManage 已被替换为受控实时重开线程 https issues apache org jira browse LUCENE
  • 在 C# 中转换 VbScript 函数(Right、Len、IsNumeric、CInt)

    同样 我在 VbScript 中得到了以下代码 您能建议一下 C 中的等效代码吗 Function GetNavID Title getNavID UCase Left Title InStr Title 1 End Function 我已
  • Laravel Blade:@extends('adminlte::page') 中参数中的双列是什么意思

    我想使用这个管理面板 https github com jeroennoten Laravel AdminLTE https github com jeroennoten Laravel AdminLTE 但我不明白这个语法 extends
  • 即使使用 return 语句,带有 forEach 的函数也返回未定义

    我只是创建一个函数来检查对象数组中某些内容的值 但由于某种原因它不断返回undefined 这是为什么 Demo http jsfiddle net cNYwz 1 http jsfiddle net cNYwz 1 var data Ke
  • WPF - 普通 [标签:输入] 控制的最佳实践

    我想知道 这是在 WPF 中获取众所周知的标签输入 或输出 无关紧要 组合的最佳和最快的方法 这是一个简单的任务 只需考虑 对象 ME 的快速输出 名字 克里斯蒂安 年龄 28 心情 好 我知道 我可以使用带有文本块的网格 但说实话 这个
  • 如何将多个值存储到一个键(java)

    我搜索一个可以存储多个键值对的数据结构 数据基本上是这样的 1 value 1 2 value 2 于是我想到了使用HashMap 遗憾的是 这对我不起作用 因为一个键可能会出现多个值 在上面的例子中 1 value 2 可能是另一个条目
  • 如何在 Azure DevOps 发布管道中保存测试结果

    在发布管道期间 我将启动 Selenium 测试 如果这些测试失败 则会进行屏幕截图 我正在寻找一种上传它们的方法 以便我可以查看它们并检查出了什么问题 我设法将它们压缩 但不幸的是 所有上传方法都不适用于发布管道 有没有办法在发布管道期间
  • 如何从网上获取源代码?

    我正在尝试从 Web 获取 HTML 源代码 我尝试这样做 u new URL url URLConnection con u openConnection con setRequestProperty User Agent Mozilla
  • 如何在Retrofit(Android)中动态设置标题

    我使用的 API 使用授权方案 需要设置特殊的 X Authorization 标头来验证请求 例如 此 Retrofit 设置非常适合其身份验证令牌为abc123 Headers X Authorization abc123 GET po