【问题标题】:Spring @Around WebClient CallsSpring @Around WebClient 调用
【发布时间】:2021-01-31 08:10:21
【问题描述】:

我正在尝试创建一个属性,该属性将通过属性验证请求中的验证码。问题的核心是我似乎找不到处理@Around()处理程序中的异步WebClient调用的方法

目标

@Captcha
@PostMapping(path = ["some-endpoint"])
fun doSomething(@RequestBody request: Mono<MyRequestWithCaptchaReponseField>) : Mono<MyResponse> { 
  // Endpoint Code
}

AOP 代码

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class Captcha()

@Aspect
@Component
class CaptchaAspect {
  @Autowired
  private lateinit var captchaClient: CaptchaService

  @Around("@annoation(Captcha)")
  @Throws(Throwable::class)
  fun validateCaptcha(joinPoint: ProceedingJoinPoint): Mono<Any> {

     val request = joinPoint.args[0] as Mono<MyRequestWithCaptchaReponseField> // This works
     return request.map { captchaClient.isValid(it.captchaResponse } // This seems to be making the call. I would throw an exception here if the captcha was invalid
                   .flatMap { joinPoint.proceed() as Mono<Any> }

  }
}

这与我得到的一样接近并且几乎可以工作,但是返回的响应是 mono&lt;MyResponse&gt; 并且似乎即使控制器端点返回 Mono&lt;MyResponse&gt;,作为 @Around() 方法它期望只返回 MyResponse。

核心问题是,如果我必须在 @Around() 方法内进行 WebClient API 调用,那么在 API 调用完成后如何处理返回 joinPoint.proceed?

【问题讨论】:

  • 这有什么问题?你有错误吗?
  • 这个家伙实际上说没有返回响应,我有点困惑。如果我将最后一个 flatMap 更改为地图,那么它会返回一个 Mono 并将其序列化为响应。它只有一个 scanAvailable 字段

标签: spring kotlin aop spring-webflux


【解决方案1】:

我想出了一个办法

@Aspect
@Component
class CaptchaAspect {
  @Autowired
  private lateinit var captchaClient: CaptchaService

  @Around("@annoation(Captcha)")
  @Throws(Throwable::class)
  fun validateCaptcha(joinPoint: ProceedingJoinPoint): Mono<Any> {

     val request = joinPoint.args[0] as Mono<MyRequestWithCaptchaReponseField> // This works
     return joinPoint.proceed(arrayOf<Any>(request.filterWhen { r -> {
       if (r is MyRequestWithCaptchaReponseField) {
         this.captchaClient.isValid(r.captchaResponse)
       } else {
         throw Exception("Request should have a captcha field")
       }
     })
  }
}

ProceedingJoinPoint.proceed 可以采用一个映射到控制器操作参数的数组。因此,您可以劫持 arg[0],并在发送之前附加您的逻辑。这些管道步骤在控制器方法中的任何内容之前执行。我已将我的 captchaClient.isValid 调用更改为 filterWhen 总是抛出异常或返回 Mono.just(true)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-29
    • 2020-05-21
    • 1970-01-01
    • 2020-07-25
    • 2018-09-16
    • 2021-01-28
    • 2019-11-18
    • 1970-01-01
    相关资源
    最近更新 更多