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

如何使用@控件建议来处理来自反应式堆栈的Web客户端错误(Web通量->Spring)

姜森
2023-03-14

我使用weblux中的webClient向远程服务器发送请求。此时,我可以得到错误400。我需要拦截它并将其发送到客户端。

webClient
                        .post()
                        .uri(
                            
                        )
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .body(
                            BodyInserters
                                .fromFormData()
                                .with()
                                .with()
                
                        )
                        .retrieve()
                        .onStatus(
                            HttpStatus::isError, response -> response.bodyToMono(String.class) // error body as String or other class
                                .flatMap(error -> Mono.error(new WrongCredentialsException(error)))
                                )
                        .bodyToMono(TResponse.class)
                        .doOnNext(...);
  • 错误
@ControllerAdvice
@Slf4j
public class ApplicationErrorHandler {

  @ExceptionHandler(WrongCredentialsException.class)
    public ResponseEntity<ErrorResponse> handleResponseException(WrongCredentialsException ex) {
      //  log.error("Error from WebClient - Status {}, Body {}", ex.getRawStatusCode(), ex.getResponseBodyAsString(), ex);

      ErrorResponse error = new ErrorResponse();
      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
          .body(error);
    }

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {

    private String errorCode;

    private String message;
}

  • rest api

@后映射

  public ResponseEntity<String> send(@RequestBody Dto dto) {

        log.debug("An notification has been send to user");

        return new ResponseEntity<>(HttpStatus.OK);
    }

我尝试了这里的选项,但没有成功。有人能解释它是如何工作的,以及如何为我的情况配置它吗?

共有1个答案

江礼骞
2023-03-14
  • 第一个案例
return Objects.requireNonNull(oauthWebClient
                .post()
                .uri(uri)
                .bodyValue(dto)
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .exchangeToMono(response -> {

                    HttpStatus httpStatus = response.statusCode();

                    if (httpStatus.is4xxClientError()) {
                        getErrFromClient(response, httpStatus);
                    }

                    if (httpStatus.is5xxServerError()) {
                        getErrFromServer(response, httpStatus);
                    }

                    return Mono.just(ResponseEntity.status(response.statusCode()));
                })
                .block())
                .build();
    }

    private void getErrFromServer(DtoResponse response, HttpStatus httpStatus) {

        String err = response.bodyToMono(String.class).toString();
        log.error("HttpStatus: {}, message: {}", httpStatus, err);

        HttpHeaders httpHeaders = response.headers().asHttpHeaders();

        List<String> errorBody = httpHeaders.get("errBody");

        assert errBody != null;
        throw new CustomException(
                "{ HttpStatus : " + httpStatus + " , message : " + errBody + " }");
    }

    private void getErrFromClient(DtoResponse response, HttpStatus httpStatus) {

        String err = response.bodyToMono(String.class).toString();

        log.error("HttpStatus: {}, err: {}", httpStatus, err);

        HttpHeaders httpHeaders = response.headers().asHttpHeaders();
        List<String> errorBody = httpHeaders.get("errBody");

        assert errBody != null;
        throw new CustomException(
                "{ HttpStatus : " + httpStatus + " , message : " + errBody + " }");
    }

  • 然后
@ControllerAdvice
public class HandlerAdviceException {

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<ErrorResponse> handleCustomException(CustomException e) {

//here your code
//for example:

        String errMessage = e.getLocalizedMessage();

        return ResponseEntity
                .internalServerError()
                .body(new ErrorResponse(ErrorCode.INTERNAL_ERROR, errMessage));
    }

}

  • 第二种情况
          return webClient
            .post()
            .uri(
              properties......,
              Map.of("your-key", properties.get...())
            )
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .body(
              prepare....()
            )
            .retrieve()
            .bodyToMono(TokenResponse.class)
            .doOnSuccess(currentToken::set);
        }

在这里,如果成功,您将获得所需的结果,但如果发生错误,则只需要在建议控制器中为WebClientResponseException配置侦听器。

@ControllerAdvice
@Slf4j
public class CommonRestExceptionHandler extends ResponseEntityExceptionHandler {

  @ExceptionHandler(WebClientResponseException.class)
  protected ResponseEntity<ApiErrorResponse> handleWebClientResponseException(WebClientResponseException ex) {

    log.error(ex.getClass().getCanonicalName());

    String errMessageAdditional = .....

    final ApiErrorResponse apiError = ApiErrorResponse.builder()
      .message(ex.getLocalizedMessage())
      .status(HttpStatus.UNAUTHORIZED)
      .build();
//if it needs
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add(.......);

    return new ResponseEntity<>(apiError, httpHeaders,  apiError.getStatus());
  }
}
 类似资料:
  • 我试图使用Spring反应式WebClient将文件上传到Spring控制器。控制器非常简单,看起来像这样: 当我使用这个控制器与cURL一切正常 multipartFile转到正确的参数,其他参数进入Map。 当我尝试从WebClient做同样的事情时,我被卡住了。我的代码如下所示: 这会导致400错误 有人知道如何解决这个问题吗?

  • 我试图测试Spring反应式Webclient的默认超时。为此,我创建了一个需要 10 小时才能返回响应的 rest endpoint。 我使用spring-reactive Webclient创建了一个rest客户端。但我看到,springReactiveWebclient一直在等待10个小时。 spring reactive Webclient没有任何默认超时吗?

  • 例如,在本文中,我试图理解为什么在流中使用flatmap()(直接从引用中粘贴副本) AFAIK,应用于流的平面图会为流中的每个输入值产生任意数量的值(0... n)。所以一个平面图需要一个产生流的函数。 通量发射0个或多个项目,然后可选地完成或偏离。 那么,响应流上到底发生了什么?这是接收响应流并发出0个或更多类警报对象的函数吗?因此,如果我们

  • 我正在spring应用程序中使用web客户端 我在执行相同操作时面临内存泄漏问题 我正在使用下面的代码获取来自服务的非2xx响应的响应体: 我的问题是,如果我在responseMono上使用dispose方法,处理过程需要很长的时间,而没有它,我会面临内存泄漏问题。我在这里做错什么了吗?

  • 伙计们,在我的控制器中执行rest后,我有问题从变量中获取数据。这里有一个例子来说明我的问题。 控制器 JavaScript drawDiagram.html null

  • 让我们假设以下两种情况,一个控制器产生一些随机数并带有延迟: 1)反应性Spring5反应性应用: 2)传统的Spring MVC与: 从HTTP客户端(浏览器、AJAX请求)的角度来看,这两种场景之间没有任何区别。我的意思是,客户端将等待所有结果发送,并且在提交整个响应之前不会处理它们。 也就是说,尽管spring web Responsive让我们认为它在生成结果时会将结果发送回去,但实际上情