Retrofit 2 - 在 api 级别添加标头的优雅方式

2024-04-16

我的改装2(2.0.2当前)客户端需要向请求添加自定义标头。

我正在使用一个Interceptor将这些标头添加到所有请求中:

OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        final Request request = chain.request().newBuilder()
                .addHeader("CUSTOM_HEADER_NAME_1", "CUSTOM_HEADER_VALUE_1")
                .addHeader("CUSTOM_HEADER_NAME_2", "CUSTOM_HEADER_VALUE_2")
                ...
                .addHeader("CUSTOM_HEADER_NAME_N", "CUSTOM_HEADER_VALUE_N")
                .build();

        return chain.proceed(request);
    }
});


Retrofit retrofitClient = new Retrofit.Builder()
        .baseUrl(baseUrl)
        .client(httpClient)
        .build();

我总是想添加一些标头,但我只需要根据特定端点的要求添加一些标头,例如用户是否需要进行身份验证。

我希望能够在 api 级别进行控制,例如使用注释,例如:

public interface MyApi {
    @NO_AUTH
    @POST("register")
    Call<RegisterResponse> register(@Body RegisterRequest data);

    @GET("user/{userId}")
    Call<GetUserResponse> getUser(@Path("userId") String userId);
}

当发送请求到register无需添加身份验证令牌,但缺少身份验证令牌的请求@NO_AUTH注释将具有令牌标头。

据我了解,Retrofit 2 不支持自定义注释,虽然我发现了这个解决方法使用 Retrofit 2 自定义注释 https://medium.com/@andretietz/custom-annotations-with-retrofit-2-8701ca7ce102#.79dg4wb8v,好像有点太多了。

我想避免需要每个请求传递这些标头,例如:

public interface MyApi {
    @POST("register")
    Call<RegisterResponse> register(@Body RegisterRequest data);

    @GET("user/{userId}")
    Call<GetUserResponse> getUser(@Header("AuthToken") String token, @Path("userId") String userId);
}

每次调用该方法而不是在拦截器中执行此操作(因为我可以静态访问标头值)时,感觉都是多余的。
我只是需要以某种方式知道我的Interceptor.intercept实现此特定请求是否应具有特定标头。

知道我怎样才能做到这一点吗?
我更喜欢通用的解决方案,不仅适用于身份验证令牌的情况,而且也欢迎特定的解决方案。 谢谢


我想出了一个非常简单而优雅(在我看来)的解决方案来解决我的问题,也可能适用于其他场景。

我用Headers注释来传递我的自定义注释,并且由于 OkHttp 要求它们遵循Name: Value格式,我决定我的格式是:@: ANNOTATION_NAME.

所以基本上:

public interface MyApi {
    @POST("register")
    @HEADERS("@: NoAuth")
    Call<RegisterResponse> register(@Body RegisterRequest data);

    @GET("user/{userId}")
    Call<GetUserResponse> getUser(@Path("userId") String userId);
}

然后我可以拦截请求,检查我是否有带有名称的注释@。如果是这样,我会获取该值并从请求中删除标头。
即使您想要拥有多个“自定义注释”,这也很有效:

@HEADERS({
    "@: NoAuth",
    "@: LogResponseCode"
})

以下是提取所有这些“自定义注释”并将其从请求中删除的方法:

new OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        List<String> customAnnotations = request.headers().values("@");

        // do something with the "custom annotations"

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

Retrofit 2 - 在 api 级别添加标头的优雅方式 的相关文章

  • Java中的整数除法[重复]

    这个问题在这里已经有答案了 这感觉像是一个愚蠢的问题 但我在 Java 文档中找不到答案 如果我声明两个 int 然后将它们相除 到底发生了什么 他们是否转换为floats doubles首先 划分 然后投射回integer 或者除法是作为
  • 如何从 ArrayList 中删除空白项。不删除索引

    public class ArrayListTest public static void main String args ArrayList al new ArrayList al add al add name al add al a
  • Java中printf左对齐

    当我运行该程序时 阶乘值右对齐 有没有办法让它左对齐 同时保持中间 50 个空格 public class Exercise 5 13 public static void main String args int numbers 1 2
  • 当线程无法访问所有已用堆时查找 Java 内存泄漏

    我正在研究基于 Java 的大型系统中潜在的内存泄漏 或至少是内存浪费 JVM 运行时的最大堆大小为 5 GB 2 3GB 堆使用量是应用程序的预期基准 可能会有更高的峰值 在我正在调查的过载场景中 堆被填满 使用 Eclipse Memo
  • 添加样式后如何重置回默认CSS?

    基本上 我通过添加如下样式类来更改 javafx 中文本字段的 css textfield getStyleClass add textfieldstyle 但后来我希望能够将其恢复到原来的样子 但由于本例中的原始外观是 JavaFX 的默
  • 如何使用 mongoTemplate 实现 Mongodb Collection 的分页

    我是 mongoDb 中的菜鸟 我需要为任何特定集合实现分页 例如说 我有一个 Foo 集合 并且有一个返回 Foo 集合中所有记录的函数 public List
  • java中数字字符串间隔排序

    我正在与一些人一起上一个人课 其中有姓名 年龄范围等详细信息 年龄区间为 0 5 6 10 11 30 31 45 46 50 50 100 100 110 我正在上 Person 课name ageBand字符串间隔及其参数化构造函数 g
  • 当服务器仅从请求中读取标头时,Http 客户端未收到响应

    我在 Java 中搞乱了 HTTP 和套接字 希望你能对此有所了解 当我用 Java SE 11 编写的 HTTP 服务器没有读取整个请求然后响应时 客户端不会收到它或收到错误 这是为什么 在服务器读取整个请求之前 客户端是否无法读取响应
  • 从 Java 监听系统鼠标点击

    我的主要目的是计算特定应用程序上的鼠标点击次数 想象一下 我在 PC 上打开了 Microsoft Word 和 Web 浏览器 我的 Java 代码应该告诉我单击 Word 和 Web 浏览器的次数 我需要应用程序名称和点击次数 我怎样才
  • Java:使用类型参数访问私有构造函数

    这是后续这个关于java私有构造函数的问题 https stackoverflow com questions 2599440 accessing the private constructor 假设我有以下课程 class Foo
  • 将分区扩展到另一级

    根据下图来自春季批量文档 http docs spring io spring batch reference html scalability html partitioning 主步骤被划分为六个从步骤 它们是主步骤的相同副本 我的问题
  • JAXB 和 complexType 与其元素之一共享名称会生成不正确的代码

    我有这个 xsd 它有点糟糕 但我必须使用它来避免更改我正在编写的 servlet 的接口 请求 响应接口的 xsd 包含以下行
  • 如何从属性中获取枚举值

    我有一个带有值的枚举VALID and INVALID 它们有一个与之关联的布尔属性 我想根据我提供的布尔值获取枚举值 如果是true我应该得到VALID 如果是false我应该得到INVALID 我想根据成员变量的值 在如下所示的 get
  • 如何在 Spring Boot 中跳过将某些 @Entity 类创建为 h2(内存中)数据库中的表?

    我正在尝试构建一个使用 2 个数据源的 Spring Boot 应用程序 我现在的主要数据库是内存数据库 仅用于测试目的 其中的表是在我创建的 sql 文件的帮助下填充的 另一个数据库 oracledb 具有已填充的表 我想实现什么目标 我
  • Java如何处理IF语句和效率

    我只是好奇 Java 实际是如何工作的if声明 注意 当我在下面说 组件 时 我指的是语句检查的各个部分 例如a b c 哪个在计算方面更有效 if a b c do stuff or if a if b if c do stuff 我之所
  • 字符串包含相同的字符但仍然不同[重复]

    这个问题在这里已经有答案了 我正在尝试读取一个 txt 文件并使用每个句子作为团队的名称 同时使用该名称查找另一个 txt 文件以获取其内容 所有 txt 文件都位于我的资产文件夹的根目录中 第一个 txt 文件工作正常 我使用assetm
  • 如何将 HTML 转换为保留换行符的文本

    我如何将 HTML 转换为保留换行符的文本 由 br p div 等元素生成 可能使用NekoHTML http nekohtml sourceforge net 或任何足够好的 HTML 解析器 Example Hello br Worl
  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • GWT 和身份验证

    保护 GWT Tomcat 应用程序执行身份验证和授权的最佳策略是什么 有两种基本策略 确保入口点安全 确保远程服务的安全 确保入口点安全 最简单的方法是使用常规 Web 应用程序安全工具限制对 GWT 生成的 html js 文件的访问
  • 在 WildFly 10 中添加 jar 作为部署

    有没有办法 我们可以将 jar 部署为库 部署WildFly 10就像我们可以做到的那样weblogic服务器 或者我们可以将 jar 放在服务器的任何文件夹中并将这些依赖项定义为provided 我得到了什么部署方式jars on Wil

随机推荐

  • MEAN 堆栈的文件夹结构

    我正在学习有关 MEAN 堆栈的教程 并且希望有一个干净的文件夹结构可供使用 我读过很多文章 说应用程序的每个 我们称之为 模块都有一个文件夹 并将视图 模型 控制器 等组合在一起 我喜欢这种方法 并且我已经开始这样做了 但是我需要一些帮助
  • 如何用SDL2和OpenGL画三角形?

    我正在使用 C 中的 SDL2 和 OpenGL 开发一个简单的应用程序 问题是我的程序没有绘制三角形 Rect hpp 绘制三角形的类 ifndef Rect hpp define Rect hpp include
  • 同一个 javac 编译器是否可以编译同一组源文件,但生成不同校验和的类文件?

    我试图比较这个结果 在蚂蚁中
  • 安装cassandra时出错

    我正在尝试按照此处的说明在 ubuntu 16 04 LTS 上安装 apache cassandra gt http docs datastax com en cassandra 3 x cassandra install install
  • 如何在另一个角度2分量中设置变量

    我正在构建一个 Angular 4 应用程序 我有 2 个单独的页面 一个详细信息页面和一个编辑页面 每个页面都有自己的组件 当用户在 编辑 页面上编辑模型时 我将它们重定向回 详细信息 页面 如下所示 This is within my
  • 如何访问废弃的函数参数?

    在 Lua 中 调用带有多余参数的函数将简单地丢弃这些参数 有没有可能与debug库来访问这些被丢弃的参数 我不是在寻找可变参数函数 function test local info debug getinfo 1 u print info
  • PASSWORD_DEFAULT 与 PASSWORD_BCRYPT

    PASSWORD DEFAULT 和 PASSWORD BCRYPT 有什么区别 他们都使用Blowfish加密算法吗 算法中的成本是什么 如何在 PHP 中设置 password hash 产生 255 哈希长度而不是 60 现在PASS
  • RubyMine 无法识别 git 存储库中的 gem

    我们有一个带有自定义 gem 的 git 存储库 要安装它 Gemfile 有一行 gem my gem git gt email protected cdn cgi l email protection my gem git 安装 gem
  • 在 Spark 2.4 中使用 Delta Lake 源时出错 (Hdinsight)

    出现以下错误 相同的代码在 Databricks 中有效 但在 Hdinsight 中无效 我还在类路径中添加了 delta 库和 hadoop azure 库 io delta delta core 2 11 0 5 0 org apac
  • Android Cordova 插件中的请求权限不会提示用户

    我正在尝试编写一个 Cordova 插件 以便为离子混合应用程序提供 Facebook 聊天头像浮动图标 这需要 SYSTEM ALERT WINDOW 权限 由于 Android M 及以上版本要求用户在应用程序第一次启动时授予权限 因此
  • JS 数组在子组内排序

    我有这个 JS 数组 Event code BW 114 Interest area Nursing and midwifery Start time 9 00 AM End time 3 00 PM Session type Tour a
  • 如何在Java中打印递归程序中的值?

    我正在尝试使用递归程序打印一个序列 该序列从一个值开始 达到最大值 然后返回到原始值 程序不能使用静态变量或全局变量 也不能使用数组 Ex f 5 10 prints 5 6 7 8 9 10 9 8 7 6 5 我想我已经有了这个概念 至
  • String类如何重写+运算符?

    为什么在 Java 中 当 String 是一个类时 您可以使用 运算符添加字符串 在里面String java代码我没有找到这个运算符的任何实现 这个概念违反了面向对象吗 我们看一下Java中的以下简单表达式 int x 15 Strin
  • Python 多处理安装:命令“python setup.py Egg_info”失败,错误代码为 1

    尝试安装 pip install multiprocessing 出现错误 Collecting multiprocessing Using cached multiprocessing 2 6 2 1 tar gz Complete ou
  • PHP 方法调用报告错误,该错误是未定义的方法

    我相信我的类是正确的 但是当我尝试回显类的输出时 我在第 28 行收到错误 echo 你的全名 行是第 28 行 任何帮助都会很好 这是我创建函数的地方 检索全名 public function retrieve full name ful
  • 复制 Photoshop sRGB 到 LAB 转换

    我想要实现的任务是复制 Photoshop RGB 到 LAB 的转换 为简单起见 我将描述我如何仅提取 L 通道 提取 Photoshop 的 L 通道 这是 RGB 图像 其中包括所有 RGB 颜色 请点击下载 为了提取 Photosh
  • 以声明方式从 Postgres 字符串中获取最后一个单词

    编辑 这个问题的原始标题是 以声明方式获取 Postgres 数组的最后一个元素 Postgres中如何获取数组的最后一个元素 我需要以声明方式执行此操作 因为我想将其用作 ORDER BY 标准 我不想为它创建一个特殊的 PGSQL 函数
  • 解决实现 ISerialized 的对象的循环引用

    我正在编写自己的 IFormatter 实现 但我想不出一种方法来解决两个都实现 ISerialized 的类型之间的循环引用 这是通常的模式 Serializable class Foo ISerializable private Bar
  • 刷新浏览器后 Font Awesome 图标消失

    刷新页面 F5 后 我的字形从 Internet Explorer 11 网页消失 但是 当我通过单击其菜单链接打开网页 首次刷新后 时 页面显示正确 在 Chrome 中 即使按 F5 后也能正常工作 我正在运行 Bootstrap v3
  • Retrofit 2 - 在 api 级别添加标头的优雅方式

    我的改装2 2 0 2当前 客户端需要向请求添加自定义标头 我正在使用一个Interceptor将这些标头添加到所有请求中 OkHttpClient httpClient new OkHttpClient httpClient networ