当前位置: 首页 > 知识库问答 >
问题:

RouterFunction中的Spring-Webflux错误处理

萧鹏云
2023-03-14

我是Spring gateway cloud(Spring Reactor)的新手。我想实现聚合层,它将从两个微服务(如RealAPI gateway)下载数据。据我所知,在Spring Cloud Gateway中,它需要以反应式方式实现。

我发现RouterFunction可以创建一个网关endpoint来实现POST到其中一个微服务。它可以工作,但当微服务返回BAD_状态或其他时,我的spring网关的响应只有500个内部服务器错误,但我想要完整的消息。

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

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

我有handler(现在很原始,我正在学习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通过方法向特定微服务发出post请求:

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请求中引发异常,将状态代码、消息等转发给RouterFunction的响应,是否有一种方法可以让标准的错误处理程序具有响应等?

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

在spring cloud gateway中,是否可以使用阻塞RestTemplate和synchronus@RestController编写它?

共有1个答案

越安翔
2023-03-14

我找到了解决方案:

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));
      }
    };
  }
}
 类似资料:
  • 现在Spring5中有两种公开HTTPendpoint的方法。 null 使用任何人的方法是否有性能差异?从头开始编写应用程序时,我应该使用哪一个。

  • 我想在以下条件下抛出自定义异常: > 如果我得到了json格式的正确错误响应,我想反序列化它,并在onStatus()中抛出名为CommonException的异常 如果作为响应的一部分接收HTML内容或反序列化未成功执行,则我希望抛出GenericeException,这是我在onErrorMap()中创建的 在抛出GenericException时,我希望将从下游响应获得的相同HttpStat

  • SI5+支持,这意味着我们现在可以构建一个反应消息传递系统。然而,这也意味着设计已经考虑周全,通常的错误处理方法不起作用。在反应流中,消息是(),它不会引发异常,但会发出错误通知。因此,消息上设置的错误通道标头是无用的,因为SI不知道导致了错误。考虑以下代码: 上面的代码片段中缺少的是将异常发送到消息上配置的错误通道。我们怎么能这么做?

  • 由于有很多方法,如onErrorReturn、onErrorResume等,所以哪一个是正确的方法,以处理mono和flux的Reactive Spring webflux中的错误?

  • 我在尝试处理调用Spring WebFlux的web客户机的不同错误时遇到了麻烦。 我如何修改我的代码,使它返回我生成的自定义消息?

  • 我正在编写一个java适配器,用于向WebService发布一些内容。在http服务中,我使用一个ExceptionHandler: 如果我用卷曲/邮递员来称呼的话,那很管用。 在成功的情况下,我希望从location头返回字符串。但是,例如,如果http-status为400,我如何抛出异常,并将正文中的错误消息添加到异常中呢? 谢谢