Spring 反应式应用程序上的请求/响应主体的副本?

2024-04-25

我正在研究访问 HTTP 请求和响应主体以在 Spring 反应式应用程序中进行跟踪的最佳方法。

对于以前的版本,我们利用 Servlet 过滤器和 Servlet 请求包装器来使用传入请求的输入流并保存其副本以异步处理跟踪(我们将它们发送到 Elasticsearch)。

但对于 Spring 反应式应用程序(使用 webflux),我想知道在解码请求之前访问请求的最合适方法是什么。有什么想法吗?


事实证明这可以使用提供的来实现装饰者: ServerWebExchangeDecorator, ServerHttpRequestDecorator and ServerHttpResponseDecorator, 分别。

这是一个示例请求装饰器,它累积了DataBuffer请求的默认订阅者读取的内容:

@Slf4j
public class CachingServerHttpRequestDecorator extends ServerHttpRequestDecorator {

    @Getter
    private final OffsetDateTime timestamp = OffsetDateTime.now();
    private final StringBuilder cachedBody = new StringBuilder();

    CachingServerHttpRequestDecorator(ServerHttpRequest delegate) {
        super(delegate);
    }

    @Override
    public Flux<DataBuffer> getBody() {
        return super.getBody().doOnNext(this::cache);
    }

    @SneakyThrows
    private void cache(DataBuffer buffer) {
        cachedBody.append(UTF_8.decode(buffer.asByteBuffer())
         .toString());
    }

    public String getCachedBody() {
        return cachedBody.toString();
    }

只要确保,当你装饰ServerWebExchange通过了WebFilter,你还覆盖getRequest()也返回请求装饰器:

public final class PartnerServerWebExchangeDecorator extends ServerWebExchangeDecorator {

    private final ServerHttpRequestDecorator requestDecorator;
    private final ServerHttpResponseDecorator responseDecorator;

    public PartnerServerWebExchangeDecorator(ServerWebExchange delegate) {
        super(delegate);
        this.requestDecorator = new PartnerServerHttpRequestDecorator(delegate.getRequest());
        this.responseDecorator = new PartnerServerHttpResponseDecorator(delegate.getResponse());
    }

    @Override
    public ServerHttpRequest getRequest() {
        return requestDecorator;
    }

    @Override
    public ServerHttpResponse getResponse() {
        return responseDecorator;
    }

}

在过滤器上:

@Component
public class TracingFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return chain.filter(new PartnerServerWebExchangeDecorator(exchange));
    }
}

可以这样使用(注意静态导入的函数):

@Bean
public HttpHandler myRoute(MyHandler handler) {
    final RouterFunction<ServerResponse> routerFunction =
        route(POST("/myResource"), handler::persistNotification);
    return webHandler(toWebHandler(routerFunction))
        .filter(new TracingFilter())
        .build();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring 反应式应用程序上的请求/响应主体的副本? 的相关文章

随机推荐

  • Elixir 中的递归和匿名函数

    我正在尝试定义一个匿名函数来执行点积 我可以将其编码为私有函数 没有任何问题 但我正在努力解决匿名函数语法 我知道我可以以不同的方式实现这一点 但我试图了解如何使用模式匹配和递归来定义匿名函数 这是我当前的实现 dot fn i input
  • 最大覆盖不相交间隔

    假设您有 k 无法尝试所有可能的子集 2 k 不可行 贪婪方法按 a i 区间覆盖算法 排序 按 b i 最大不相交区间数算法 排序不起作用 不知道是否有动态程序解决方案 考虑到输入的大小 我认为解决方案应该是 O k log k 或 O
  • JavaScript 中的奇怪字符导致其无法加载

    我的网站在本地主机上运行良好 我的 JavaScript 正在加载并运行良好 但是当我部署站点时 脚本不起作用 当我右键单击页面并说查看源代码 然后查看链接的脚本文件时 文件开头有一些奇怪的字符 函数 在本地主机上 我的脚本文件像这样开始
  • 如何在powerpoint vba中制作进度条?

    如何使用 PowerPoint VBA 制作进度条 它应该作为幻灯片上的动画来完成 这是您要找的吗 http www pptfaq com FAQ00597 htm http www pptfaq com FAQ00597 htm
  • `npm i` 命令有什么作用?

    什么是i在 npm CLI 中执行命令 我看到它是这样使用的 npm i package The iflag 是一个别名install so npm i package 是相同的 npm install package 从文档中 npm i
  • 如何创建可以跨多个页面或在框架/iframe 内访问的全局 JSP 变量?

    简而言之 如何在 JSP 中创建全局变量 以便可以跨其他 JSP 页面和 或内部框架 iframe 访问它 我尝试了 但出现错误 无法在单独的 jsp 页面中解析该变量 是否有可能在多个页面中访问 JSP 变量而无需求助于查询字符串 会话变
  • git tag -l 不会删除已删除的标签

    这是场景 我将我的存储库克隆到一个定期更新的目录 git pull 现在我又创建了一个目录并签出了相同的存储库 我必须创建一些标签 但我错误地创建了名称错误的标签 所以我从第一个目录中删除了标签 git tag d old git push
  • 错误:SPAN_EXCLUSIVE_EXCLUSIVE 跨度的长度不能为零

    我的 Android 应用程序出现问题 我有一个按钮和一个关联的事件 但是当我第一次单击时出现错误 跨度不能有零长度 但是当我第二次单击时 事件 onclick 运行良好 看看我的java代码 public class MainActivi
  • 如何调试 Apache mod_rewrite

    我对 mod rewrite 有两个主要问题 当我的规则无效时 不会报告任何有意义的错误 To reliably test each modification I have to erase Google Chrome s cache Th
  • 新的 Basecamp api 告诉我该地址没有 Basecamp 帐户

    我是 Basecamp api 的新手 在尝试最简单的示例时 curl u user pass H User Agent MyApp email protected cdn cgi l email protection https base
  • Pyspark 删除数据帧列中的多个字符

    看看 pyspark 我明白了translate and regexp replace帮助我了解数据框列中存在的单个字符 我想知道是否有一种方法可以在regexp replace or translate这样它就会解析它们并用其他东西替换它
  • 谁能解释一下这些 XSS 测试字符串吗?

    最近我发现了这个关于 XSS 和 Web 应用程序安全的教程 gt https www owasp org index php XSS Filter Evasion Cheat Sheet XSS Locator https www owa
  • 你能帮我使用 Selenium 单击“添加到购物车”按钮吗?

    我正在尝试做一个教程并在 python 中学习 Selenium 但是我似乎无法让 Selenium 使用 find element by class 或 find element by XPATH 单击 添加到购物车 按钮 问题是检查商品
  • DELETE_ON_CLOSE 的用处

    互联网上有很多示例展示如何使用StandardOpenOption DELETE ON CLOSE 例如 Files write myTempFile StandardOpenOption DELETE ON CLOSE 其他例子类似地使用
  • 在 Swift 中,如何根据一个数组对另一个数组进行排序?

    在 Swift 中 假设我有两个数组 var array1 Double 1 2 2 4 20 0 10 9 1 5 var array2 Int 1 0 2 0 3 现在 我想按升序对 array1 进行排序并相应地重新索引 array2
  • 查找 Html 的哪些部分对 PHP 无效

    我尝试了几种方法来找出 html 字符串的哪一部分无效 dom gt loadHTML badHtml tidy gt cleanRepair simplexml load string badHtml 没有人明确说明 html 的哪一部分
  • ASP.NET MVC - 从视图部分更新模型

    我只是想知道人们是如何应对这种情况的 这似乎是我使用 MVC 和 ORM 本例中为 NHibernate 的一个弱点 假设您的模型中有一个细粒度且复杂的实体 您可能有一个管理页面来管理此类对象 如果实体很复杂 您不太可能以一种形式修改整个实
  • 从文本框值插入数字(十进制)数据

    我对以下问题感到困惑 我有一个 C Windows 窗体 应用程序 它连接到 SQL Server DB 并且在 INSERT SELECT UPDATE 方面没有任何问题 直到我开始处理数字数据 这个应用程序的目的是管理员工 他们的合同
  • 在c中使用printf打印常量指数值

    I used e格式说明符 尝试过 3 2e or 4 3e Example if var 0 001342 然后我想打印0 1342e 02 但打印1 342e 03 if var 0 543124 然后我想打印54 3124e 02 但
  • Spring 反应式应用程序上的请求/响应主体的副本?

    我正在研究访问 HTTP 请求和响应主体以在 Spring 反应式应用程序中进行跟踪的最佳方法 对于以前的版本 我们利用 Servlet 过滤器和 Servlet 请求包装器来使用传入请求的输入流并保存其副本以异步处理跟踪 我们将它们发送到