有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在WebFilter中有条件地从Mono返回?

我不确定我问的是否正确,所以这里有一个我想做的示例(使用带阻塞的命令式)

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想要返回一个aMono<Object>,但是我的过滤器需要一个Mono<Void>,所以我只是在其中插入了一个.then()。我肯定那是不对的

我的代码正在编译并到达最后的switch语句并调用正确的return语句,但是请求没有到达我的控制器。webfilter未正确转发请求。我刚刚恢复了200的状态,没有处理程序的结果

这样做的正确反应方式是什么


共 (1) 个答案

  1. # 1 楼答案

    我的意思是这样的。如果您的代码在第一次转换时没有输入,我使用.switchIfEmpty(Mono.empty())返回一些内容。您还可以创建默认的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());
        }
    }