助焊剂为空时返回404

时间:2018-11-22 16:36:09

标签: spring-webflux project-reactor

当通量为空时,我试图返回404,类似于此处:WebFlux functional: How to detect an empty Flux and return 404?

我主要担心的是,当您检查助焊剂是否包含元素时,它将发出该值,然后将其释放。当我尝试在服务器响应上使用switch如果为空时,它永远不会被调用(我暗中认为这是因为Mono不为空,只有主体为空)。

我正在做的一些代码(我的路由器类上确实有一个过滤器,用于检查DataNotFoundException以返回notFound):

Flux<Location> response = this.locationService.searchLocations(searchFields, pageToken);
return ok()
        .contentType(APPLICATION_STREAM_JSON)
        .body(response, Location.class)
        .switchIfEmpty(Mono.error(new DataNotFoundException("The data you seek is not here.")));

^这永远不会调用switchIfEmpty

Flux<Location> response = this.locationService.searchLocations(searchFields, pageToken);

return response.hasElements().flatMap(l ->{
   if(l){
       return ok()
               .contentType(APPLICATION_STREAM_JSON)
               .body(response, Location.class);
   } 
   else{
       return Mono.error(new DataNotFoundException("The data you seek is not here."));
   }
});

^这会松散hasElements上发出的元素。

是否有办法恢复hasElements中发射的元素或使switchIfEmpty仅检查正文内容?

3 个答案:

答案 0 :(得分:1)

您可以将switchIfEmpty运算符应用于Flux<Location> response

Flux<Location> response = this.locationService
        .searchLocations(searchFields, pageToken)
        .switchIfEmpty(Mono.error(new DataNotFoundException("The data you seek is not here.")));

答案 1 :(得分:1)

亚历山大写的是正确的。在定义上永远不会为空的switchIfEmpty的对象上调用ServerResponse.ok()不是空的发布者。我想以逆转方式处理这种情况,因此请先调用服务,然后将所有创建响应的方法链接起来。

    this.locationService.searchLocations(searchFields, pageToken)
            .buffer()
            .map(t -> ResponseEntity.ok(t))
            .defaultIfEmpty(ResponseEntity.notFound().build());

更新(不确定是否可以运行,但请尝试一下):

 public Mono<ServerResponse> myRestMethod(ServerRequest serverRequest) {
        return serverRequest.bodyToMono(RequestDTO.class)
                .map((request) -> searchLocations(request.searchFields, request.pageToken))
                .flatMap( t -> ServerResponse
                        .ok()
                        .body(t, ResponseDTO.class)
                )
                .switchIfEmpty(ServerResponse.notFound().build())
                ;
    }

答案 2 :(得分:1)

虽然发布的答案确实是正确的,但是如果您只想返回状态码(加上原因)并且不想摆弄任何自定义过滤器或定义自己的错误响应异常,则可以使用便捷异常类。

另一个好处是,您不必将响应包装在任何ResponseEntity对象中,尽管在某些情况下(例如,使用位置URI创建)很有用,但对于简单的状态响应来说却是过分的。

另请参阅https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/server/ResponseStatusException.html

 return this.locationService.searchLocations(searchFields, pageToken)
        .buffer()
        .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND, "these are not the droids you are lookig for")));