所以我是rx-java / rx-kotlin的新手,直到我在Micronaut(https://docs.micronaut.io/latest/guide/index.html#filters)中编写HTTP过滤器的地方才听说过它,这使我措手不及,因为我只做常规的JAX-RS过滤器。
因此,经过反复试验,我想到了这个。
return Flowable.fromPublisher(remoteClient.getPermissions(userId))
.subscribeOn(Schedulers.io())
.onErrorReturn { e ->
logger.error("Error when fetching users from remote service", e)
emptyList()
}
.switchMap { permissions ->
if (permissions.contains(somePermission)) {
chain.proceed(request)
} else {
val response = HttpResponseFactory.INSTANCE.status(
HttpStatus.FORBIDDEN,
"No user found"
)
Flowable.just(response)
}
}
代码被重写,但指向仍然有效。这里还有一些改进的空间。
[我想做的是改进异常处理,并在抛出异常的情况下返回500(例如,如果无法访问由remoteClient
调用的远程服务。我该如何做到这一点?除了上述解决方案之外,没有其他任何事情可以工作,可以为下一个观察者返回一个空列表。
您可以在onErrorReturn
运算符之后移动switchMap
运算符。如果getPermissions
发出错误,执行将跳过您的switchMap
,并在onErrorReturn
中提取:
return Flowable.fromPublisher(remoteClient.getPermissions(userId))
.subscribeOn(Schedulers.io())
.switchMap { permissions ->
if (permissions.contains(somePermission)) {
chain.proceed(request)
} else {
val response = HttpResponseFactory.INSTANCE.status(
HttpStatus.FORBIDDEN,
"No user found"
)
Flowable.just(response)
}
}
.onErrorReturn { e ->
logger.error("Error when fetching users from remote service", e)
val response = // whatever
return response
}
请注意,switchMap
内部发生的异常也会导致执行onErrorReturn
。因此,您既可以检查传递给onErrorReturn
的Exception来决定使用哪种响应,也可以将onErrorReturn
嵌入到switchMap
调用中,以防止其向下游发出异常,从而将其嵌入到chain.proceed(request)
中。