错误代码 invalid-method 错误原因: 不存在的方法名_Spring Webflux中的错误处理

Web应用程序中的错误处理环节非常重要。从客户的角度出发,必须了解请求是如何进行的,并且在发生任何错误的情况下,最重要的是向客户提供为啥会错误的原因,尤其是如果错误是由于客户的行为引起的。在不同的情况下,通知具体原因是必须的——考虑到服务器端验证,由于错误请求或简单未找到情况而导致的业务逻辑错误等等。

Webflux中错误处理的机制与Spring MVC不同。响应式应用程序的核心构建块– Mono和Flux提供了一种特殊的方式来处理错误情况,尽管旧的基于异常的错误处理在某些情况下仍可能有效,但它违反了Spring Webflux的本质。在这篇文章中,将概述有关业务错误和数据缺失时如何处理Webflux中的错误。在本文中,将不讨论技术错误,因为那是由Spring框架处理的。

我们何时需要处理Webflux中的错误

在我们进入错误处理主题之前,让我们定义我们想要实现的目标。假设我们使用常规架构构建应用程序,该架构具有垂直分层和水平分层的功能。这意味着,我们的应用程序包含三个主要层:存储库(一个用于处理数据访问),服务(一个用于执行自定义业务逻辑)和处理程序(用于处理HTTP请求/响应;将其理解为Spring MVC中的控制器)。

在存储库级别(处理外部API和所有数据访问组件的客户端,也请在这里抽象)通常发生所谓的技术错误。例如,数据库可能出了点问题,因此存储库组件将引发错误。该错误是的子类,RuntimeException如果使用Spring,则由框架处理,因此无需在这做任何事情。最后会出现500的错误代码。

另一种情况是我们所说的业务错误。在发生此类违规情况时,必须为客户提供有意义的回应。如果返回图表,则会注意到,此类错误通常发生在服务级别,因此必须对其进行处理。

那么,如何在Spring Webflux API中处理错误并提供错误响应?

从业务逻辑开始

在使用响应式Webflux之前,我们经常使用基于异常的错误处理。这意味着提供了一个自定义的运行时异常(的子类ResponseStatusException),该异常与特定的http状态映射。

但是,Webflux方法是不同的。主楼块Mono和Flux组件,这在整个应用程序的流程链(注意,从这里我指的是既Mono和Flux为Mono)。在任何级别上抛出异常都会破坏异步特性。此外,Spring反应性存储库(一个例子而已)ReactiveMongoRepository不使用异常来指示错误情况。Mono容器提供了传播错误条件和空条件的功能:

  • Mono.empty()=此静态方法创建一个Mono无需发出任何物品即可完成的容器
  • Mono.error()=此静态方法创建一个Mono容器,该容器在订阅后立即以错误终止

有了这些知识,我们现在可以设计一种假设的登录/注册流程,以处理以下情况:

1)实体不存在

2)发生错误。

如果在存储库级别发生错误,Spring将通过返回Mono错误状态进行处理。找不到所需的数据时-空Mono。我们还可以在服务内部添加一些对业务规则的验证。看一下这篇文章中重构的注册流程代码:

bc411019e9b8f1f9b3df19985bd1bf77.png

在处理程序中显示http响应

此级别可以对应于Spring MVC中的旧良好控制器。处理程序的目的是使用HTTP请求和响应,从而将业务逻辑与外部世界连接。在最简单的实现中,注册过程的处理程序如下所示:

注册处理程序

ac6b61131c8ebd26f7f569d7d51525bd.png

该代码执行以下基本操作:

  1. 接受来自HTTP请求的主体有效负载
  2. 调用业务逻辑组件
  3. 返回结果作为HTTP响应

但是,它没有利用我们在上一节中讨论的自定义错误处理的优势。当用户已经存在时,我们需要处理一种情况。为此,让我们重构此代码块:

重构了注册处理程序

2a7979ccd35972ec98b75a7db58f222e.png

在此代码中,我们可以向客户端指定错误的原因。如果用户确实存在于数据库中,我们将向409提供错误代码,因此他必须使用另一个电子邮件地址进行注册过程。那就是商业错误。对于技术错误,我们的API显示500错误代码。

我们可以验证,当我们创建一个新用户时,一切正常,预期结果是200成功代码

另一方面,如果您尝试使用相同的电子邮件地址进行注册,则API应该以400错误代码响应。

此外,我们不再需要实体success字段SignupResponse,因为使用错误代码处理了不成功的注册。我想提到的是另一种情况–空响应的问题。

特殊情况:对空结果的回应

为什么这是特例?从技术上讲,空响应不是错误,也不是业务错误或技术错误。开发人员之间有不同的意见,如何正确处理它。

让我们来看看登录流程。与登录流程相反,登录流程是一种常见情况。对于注册流程,我们必须确保该用户尚不存在,但是对于登录,我们必须知道该用户已经存在。如果没有,我们需要返回一个错误响应。

看一下login处理程序的初始实现:

d3e0fd5498f9ae7880bcac4113d756c3.png

从服务组件的角度来看,我们可以预期三种情况:

  1. 用户存在并且登录成功=返回 LoginResponse
  2. 用户存在,但登录被拒绝=返回错误
  3. 用户不存在=返回空用户

我们已经看到了如何处理处理程序中的错误。空响应情况使用switchIfEmpty方法进行管理。看一下重构的实现:

05c998d6f417c5f1594c3665bff1fbb9.png

请注意,与onErrorResume方法不同,switchIfEmpty接受替代方法Mono而不是函数作为参数。然后检查一下是否都按期运行,现有用户实体和有效凭证的登录名应返回有效响应。

如果提交的凭据错误(密码不匹配),但是用户确实存在(案例2),我们将获得Bad request错误代码。

最后,如果存储库找不到用户实体,则处理程序将回答Not found。

喜欢记得关注一下哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值