Spring @Around WebClient Calls



我正试图创建一个属性,通过属性验证请求中的Captcha。问题的核心是我似乎找不到在@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<MyResponse>,看起来即使控制器端点返回Mono<MyResponse>,作为@Around()方法,它也只期望返回MyResponse。

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

我找到了一个解决方案

@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(

相关内容

  • 没有找到相关文章

最新更新