【问题标题】:Spring Webflux error handling in RouterFunctionRouterFunction 中的 Spring Webflux 错误处理
【发布时间】:2021-12-29 08:44:59
【问题描述】:

我是 Spring 网关云(Spring Reactor)的新手。我想实现聚合层,它将从两个微服务下载数据,比如真正的 api-gateway。 据我了解,在 Spring Cloud Gateway 中,它需要以反应方式实现。

我发现 RouterFunction 可以创建一个网关端点来实现对其中一个微服务的 POST。它可以工作,但是当微服务返回 BAD_STATUS 等时,我的 spring 网关的响应只有 500 INTERNAL SERVER ERROR,但我想要完整的消息。

@Bean
  public RouterFunction<ServerResponse> createNodes(TokenFilter tokenFilter, NodesHandler nodesHandler) {

    return RouterFunctions.route()
        .POST("/nodeNew", nodesHandler::createNodes)
        .filter(tokenFilter)
        .filter(dataNotFoundToBadRequest())
        .build();
  }

我有处理程序(现在很原始,我正在学习 webflux)

public Mono<ServerResponse> createNodes(ServerRequest request) {


    return request.bodyToMono(RestNodeCreate.class)
        .flatMap(newNodeCreate -> {
          if (newNodeCreate.getAccessMethod().equals("TCPIP")) {
            return oldCatalog.createNode(Mono.just(newNodeCreate), getTokenFromRequest(request))
                .onErrorResume(throwable -> {
                  System.out.println("OLD RESPONSE ");
                  return Mono.error(throwable));
                });
          } else {
            return builNodesToNewCatalog(Mono.just(newNodeCreate))
                .flatMap(newNodeCreate1 -> newCatalog.createNode(Mono.just(newNodeCreate1)))
                .onErrorResume(throwable -> {
                  System.out.println("NEW RESPONSE ");
                  return Mono.error(throwable);
                });
          }
        })
        .flatMap(o -> ServerResponse.ok().body(Mono.just(o), Object.class));
}

还有两个服务 newCatalog 和 oldCatalog 与 WebClient 使用方法向特定微服务发布请求:

public Mono<RestNodeCreate> createNode(Mono<RestNodeCreate> node, String token) {
    return webClient
        .post()
        .uri("/nodes")
        .contentType(MediaType.APPLICATION_JSON)
        .header(HttpHeaders.AUTHORIZATION, token)
        .body(node, RestNodeCreate.class)
        .retrieve()
        .onStatus(HttpStatus::is5xxServerError,
            response -> response.bodyToMono(String.class).flatMap(s -> Mono.error(new RuntimeException(s))))
        .bodyToMono(RestNodeCreate.class);
  }

如果在 webClient 请求中抛出异常以将 statusCode、消息等转发到来自 RouterFunction 的响应以具有带有响应等的标准化错误处理程序,这是一种方法吗?

{
   "timestamp": "forwarded from webclient response",
   "statuscode": "forwarded from webclient response", 
   "message": "forwarded from webclient response"
} 

在 spring-cloud-gateway 中是否可以通过阻塞 RestTemplate 和同步 @RestController 来编写它?

【问题讨论】:

    标签: spring spring-boot spring-webflux spring-boot-actuator


    【解决方案1】:

    我找到了解决方案:

    import static org.springframework.boot.web.error.ErrorAttributeOptions.Include.EXCEPTION;
    import static org.springframework.boot.web.error.ErrorAttributeOptions.Include.MESSAGE;
    
    import java.util.Map;
    import org.springframework.boot.web.error.ErrorAttributeOptions;
    import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
    import org.springframework.boot.web.reactive.error.ErrorAttributes;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.reactive.function.server.ServerRequest;
    
    @Configuration
    public class ErrorAttributesConfiguration {
    
      @Bean
      public ErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes() {
    
          @Override
          public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
            return super.getErrorAttributes(request, options.including(MESSAGE, EXCEPTION));
          }
        };
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-06
      • 2018-06-13
      • 1970-01-01
      • 2018-07-05
      • 2018-04-15
      • 2021-08-04
      • 2019-12-04
      • 2021-07-16
      相关资源
      最近更新 更多