Spring Reactive WebFlux - 如何自定义BadRequest错误消息

2024-01-30

在我的请求处理程序中,如果传入accountId无法转换为有效的ObjectId我想捕获错误并发回有意义的消息;但是,这样做会导致返回类型不兼容,并且我无法弄清楚如何实现这个非常简单的用例。

My code:

  @GetMapping("/{accountId}")
  public Mono<ResponseEntity<Account>> get(@PathVariable String accountId) {
      log.debug(GETTING_DATA_FOR_ACCOUNT, accountId);

      try {
        ObjectId id = new ObjectId(accountId);
        return repository.findById(id)
            .map(ResponseEntity::ok)
            .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
      } catch (IllegalArgumentException ex) {
        log.error(MALFORMED_OBJECT_ID, accountId);
        // TODO(marco): find a way to return the custom error message. This seems to be currently
        //  impossible with the Reactive API, as using body(message) changes the return type to
        //  be incompatible (and Mono<ResponseEntity<?>> does not seem to cut it).
        return Mono.just(ResponseEntity.badRequest().build());
      }
  }

The body(T body)方法改变返回的类型Mono所以它是(假设一个人只是发送一个String) a Mono<ResponseEntity<String>>;但是,将该方法的返回类型更改为Mono<ResponseEntity<?>>也不起作用:

        ...
        return Mono.just(ResponseEntity.badRequest().body(
            MALFORMED_OBJECT_ID.replace("{}", accountId)));

因为它在另一个上给出了“不兼容类型”错误return陈述:

error: incompatible types: Mono<ResponseEntity<Account>> cannot be converted to Mono<ResponseEntity<?>>
            .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));

显然,将方法的返回类型更改为Mono<?>可以,但是响应是序列化的 JSONResponseEntity这不是我想要的。

我也尝试过使用onErrorXxxx()方法,但它们在这里也不起作用,因为转换错误甚至在计算 Flux 之前就发生了,而且我只是收到带有空消息的“普通”400 错误。

我能想到解决这个问题的唯一方法是添加一个message领域到我的Account反对并返回那个,但这确实是一个可怕的黑客行为。


@thomas-andolf 的回答帮助我找到了实际的解决方案。

对于将来遇到这个问题的任何人,这就是我实际解决这个难题的方法(并且,是的,您仍然需要try/catch拦截抛出的错误ObjectId构造函数):

  @GetMapping("/{accountId}")
  public Mono<ResponseEntity<Account>> get(@PathVariable String accountId) {
    return Mono.just(accountId)
        .map(acctId -> {
          try {
            return new ObjectId(accountId);
          } catch (IllegalArgumentException ex) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
                MALFORMED_OBJECT_ID));
          }
        })
        .flatMap(repository::findById)
        .map(ResponseEntity::ok)
        .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
  }

为了真正看到message在返回的正文中,您需要添加server.error.include-message=always in application.properties (see here https://stackoverflow.com/questions/62561211/spring-responsestatusexception-does-not-return-reason).

Using onError()在这里不起作用(我确实尝试过,在它的所有变体中),因为它需要Mono<ResponseEntity<Account>>并且无法从错误状态生成错误状态(添加消息正文时)。

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

Spring Reactive WebFlux - 如何自定义BadRequest错误消息 的相关文章

随机推荐

  • 导入 db phpMyAdmin - 错误格式参数不正确

    我正在尝试将生产 mysql 数据库导入本地 xampp 测试环境 通过连接到Web管理 mozff 并简单导出sql 不需要其他任何东西 然后转到本地phpmyadmin仪表板并导入 它抛出以下错误 Error 居住环境 数据库服务器 S
  • JScrollPane 滚动到最后添加的行

    我有 JTextArea 文本和 JScrollPane pane new JScrollPane text 我放置pane setAutoScrolls true 当我将一些文本附加到窗格在末尾 最后一行 滚动的组件文本时 如何获得该结果
  • 在 C# 中将 int[] 转换为 byte[]

    我知道如何长期执行此操作 通过创建所需大小的字节数组并使用 for 循环来转换 int 数组中的每个元素 我想知道是否有更快的方法 因为如果上面的方法似乎会崩溃int比一个大sbyte 如果你想要按位复制 即从一个 int 中获取 4 个字
  • 更新嵌套对象时 UseState 不重新渲染

    我通过将数据推送到旧状态对象并将其作为值返回来更新 useEffect 这段代码实际上改变了 useState 中的 series 变量 但没有重新渲染 为什么 import TimeSeries Pipeline Stream Event
  • 如何将windows上的代码文件与WSL/linux同步?

    基本上我有一些 C C 代码需要在 Linux 机器上构建和调试 不幸的是 我的 Windows 笔记本电脑没有足够的可用硬盘空间来安装某些 Linux 发行版 也没有足够的可用 RAM 来舒适地运行 VM 到目前为止 我使用 WSL 处理
  • 存储来自 Google JavaScript API 请求的响应

    在使用 Google 尝试 Google 的 Javascript API 时 我遇到了一个障碍 var response var request gapi client request path plus v1 people THEUSE
  • 如何将图像从客户端发送到服务器节点 js 反应

    我正在尝试创建上传个人资料图像方法 帮助用户在网站上上传他们的个人资料图片 但我遇到了问题 我不知道如何将图像从客户端发送到服务器并使这些图像存储在 cloudinary 或 firebase 上 我的路线如下所示 ProfileAPI j
  • 在 Cocoa Objective-C 中创建模态对话框或窗口?

    我需要创建一个模式对话框 该对话框从 nib 文件加载 并应在主窗口中单击按钮时显示 我可以在 nib 文件中创建自定义窗口 并在单击按钮时加载自定义对话框 但这不是模式对话框 我可以切换回主窗口 MyWindowController is
  • “.tt”扩展名是什么?

    我和一群人一起工作something js tt使用 Knockout 和一堆的 JavaScript 文件something else ttHTML 文件 基础设施主要是带有 Perl 服务 API 的 C 后端 我们使用这些 tt文件来
  • 优化配分函数

    这是Python中的代码 function for pentagonal numbers def pent n return int 0 5 n 3 n 1 function for generalized pentagonal numbe
  • OS X 应用程序沙箱和任意文件访问 - 更新为基于文档?

    我的 OS X 应用程序 当前未沙箱 访问用户设置的目录中包含的文件 选择带有NSOpenPanel并且在整个执行过程中都会保留对该路径的引用 文件列表是通过生成的NSDirectoryEnumerator然后我使用读取和写入这些文件AVA
  • 除了越狱之外,iDevice 上的 UDID 会改变吗?

    我有一位 Beta 测试员 在最后一个 Beta 测试周期后 4 个月 我向他发送了新版本的应用程序的第一个 Beta 测试 当她说无法加载时 我们检查了她的 UDID 它与我们 4 个月前使用的不同 所以我的配置显然不起作用 她说这和以前
  • 构建静态库

    我正在尝试建立一个 a我的 iPhone 项目的静态库 所以 我创建了一个新项目 并使用了模板Cocoa Touch Static Library 然后 在XCode 4 0 我添加我的 m and h files 我已经成功构建了该项目
  • CATransform3D 可以用来获取 Face Mesh 中的眼睛尺寸吗?

    我正在尝试使用 ARKit 的 3D Face Mesh 获取眼睛的宽度和 2 只眼睛的距离 我用过CA变换3D of ARAnchor struct CATransform3D CGFloat m11 m12 m13 m14 CGFloa
  • 在 Angular 中动态创建元素

    我的 JavaScript 经验很少 我需要在单击某个项目时添加一个菜单 我们被要求从头开始构建它 而不使用任何库 如引导组件或 JQuery 我们正在使用 Angularjs 在角度中 我想知道创建新元素的正确方法 类似我们没有的东西do
  • 如何在水晶报表中显示打印对话框?

    我想打印我的Crystal report直接到打印机 目前我正在出口到PDF 但我的客户希望将其直接发送到打印机 我怎样才能显示Print Dialog单击 打印 按钮可将报告直接打印到打印机 我想提一下 我的项目使用 C 和 asp ne
  • 在 .net core 3.1 控制台应用程序中将 nlog 与 ApplicationInsightsTelemetryWorkerService 结合使用

    我正在使用应用程序见解和 nlog 配置 net core 3 控制台应用程序 我的代码配置如下 程序 cs ConfigureLogging hostingContext logging gt logging ClearProviders
  • 由于某些错误,无法使用“git pull”

    git pull fatal unable to access https github com neilyolol aws python git error 0D0C50A1 asn1 encoding routines ASN1 ite
  • 如何设置 GMock EXPECT_CALL 来为模拟函数调用两个不同的函数

    当 测试套件 中的测试函数中调用模拟函数时 如何调用两个不同的函数 细节 模拟函数在测试函数中被调用两次 当第一次调用它时 它应该调用一个函数 测试套件中的本地函数 第二次调用时 它应该调用另一个函数 测试套件中的另一个本地函数 那么 如何
  • Spring Reactive WebFlux - 如何自定义BadRequest错误消息

    在我的请求处理程序中 如果传入accountId无法转换为有效的ObjectId我想捕获错误并发回有意义的消息 但是 这样做会导致返回类型不兼容 并且我无法弄清楚如何实现这个非常简单的用例 My code GetMapping accoun