如何从 WebFilter 中的 Mono 有条件地 return?
How do I conditionally return from a Mono within a WebFilter?
不确定我问的是否正确,所以这是我想做的事情的示例(命令式阻塞)
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThingMono = getMyThingMono();
// I Know this is not right but it's effectively what I want to do
if( myThingMono is empty ) {
return chain.filter(exchange);
} else {
MyThing thing = myThingMono.block(); // I know I can't do this
switch(thing.status) {
case A:
exchange.getResponse().setStatus(HttpStatus.BAD_REQUEST);
return exchange.getResponse().setComplete();
default:
return chain.filter(exchange);
}
}
}
这是我以反应方式获得的最接近的结果
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThingMono = getMyThingMono();
myThingMono.map(thing -> {
switch(thing.status) {
case A: return HttpStatus.BAD_REQUEST;
default: return HttpStatus.OK;
}
})
.defaultIfEmpty(HttpStatus.OK) // in case myThingMono is empty
.map(status -> {
switch(status) {
case HttpStatus.OK:
return chain.filter(exchange);
default:
exchange.getResponse().setStatusCode(status);
return exchange.getResponse().setComplete();
}
})
.then();
myThingMono 想要 return 一个 Mono<Object>
,但我的过滤器需要一个 Mono<Void>
,所以我只是将一个 .then()
塞进了它。我确定那是不对的。
我的代码编译并到达最终的 switch 语句并调用正确的 return 语句,但请求没有到达我的控制器。 Web 过滤器未正确转发请求。我只是在没有处理程序结果的情况下返回 200 状态。
执行此操作的正确反应方式是什么?
我的意思是这样的。如果您的代码没有在第一次转换时输入,我使用 .switchIfEmpty(Mono.empty())
到 return 的东西。您还可以创建默认 Mono.just(new MyThing())
.
然后我使用 flatMap
将所有逻辑 switch ...
放入其中。
enum MyThingEnum { A }
class MyThing { public MyThingEnum status; }
public class Test {
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThingMono = getMyThingMono();
return myThingMono.flatMap(thing -> {
switch (thing.status) {
case A:
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
return exchange.getResponse().setComplete();
default:
exchange.getResponse().setStatusCode(HttpStatus.OK);
return chain.filter(exchange);
}
})
.switchIfEmpty(Mono.empty());
}
private Mono<MyThing> getMyThingMono() {
return Mono.just(new MyThing());
}
}
不确定我问的是否正确,所以这是我想做的事情的示例(命令式阻塞)
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThingMono = getMyThingMono();
// I Know this is not right but it's effectively what I want to do
if( myThingMono is empty ) {
return chain.filter(exchange);
} else {
MyThing thing = myThingMono.block(); // I know I can't do this
switch(thing.status) {
case A:
exchange.getResponse().setStatus(HttpStatus.BAD_REQUEST);
return exchange.getResponse().setComplete();
default:
return chain.filter(exchange);
}
}
}
这是我以反应方式获得的最接近的结果
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThingMono = getMyThingMono();
myThingMono.map(thing -> {
switch(thing.status) {
case A: return HttpStatus.BAD_REQUEST;
default: return HttpStatus.OK;
}
})
.defaultIfEmpty(HttpStatus.OK) // in case myThingMono is empty
.map(status -> {
switch(status) {
case HttpStatus.OK:
return chain.filter(exchange);
default:
exchange.getResponse().setStatusCode(status);
return exchange.getResponse().setComplete();
}
})
.then();
myThingMono 想要 return 一个 Mono<Object>
,但我的过滤器需要一个 Mono<Void>
,所以我只是将一个 .then()
塞进了它。我确定那是不对的。
我的代码编译并到达最终的 switch 语句并调用正确的 return 语句,但请求没有到达我的控制器。 Web 过滤器未正确转发请求。我只是在没有处理程序结果的情况下返回 200 状态。
执行此操作的正确反应方式是什么?
我的意思是这样的。如果您的代码没有在第一次转换时输入,我使用 .switchIfEmpty(Mono.empty())
到 return 的东西。您还可以创建默认 Mono.just(new MyThing())
.
然后我使用 flatMap
将所有逻辑 switch ...
放入其中。
enum MyThingEnum { A }
class MyThing { public MyThingEnum status; }
public class Test {
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThingMono = getMyThingMono();
return myThingMono.flatMap(thing -> {
switch (thing.status) {
case A:
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
return exchange.getResponse().setComplete();
default:
exchange.getResponse().setStatusCode(HttpStatus.OK);
return chain.filter(exchange);
}
})
.switchIfEmpty(Mono.empty());
}
private Mono<MyThing> getMyThingMono() {
return Mono.just(new MyThing());
}
}