【问题标题】:How do custom exception in Webflux WebClient?Webflux WebClient中如何自定义异常?
【发布时间】:2019-12-30 08:00:26
【问题描述】:

在我的 webflux 应用程序中,我想通过 WebClient 发送一些请求。我想处理所有条件(200、401、403 和 ... 响应),然后响应json 到客户端。对于错误状态代码,我想使用@RestControllerAdvice,所以我必须抛出一个自定义异常,然后在控制器建议中处理自定义 json。查看示例代码:

WebClient.create().post
   .uri("URI")
   .retrieve()
   .onStatus(HttpStatus::is4xxClientError, {
       // create Mono<CustomException> 
   }
   .bodyToMono(ResponseDto.class)

现在异常处理程序如下:

@ResponseBody
@ResponseStatus(...)
@ExceptionHandler(CustomException1.class)
public void customException1(CustomException1 exception) {
   //do Something width response body
}

@ExceptionHandler(CustomException2.class)
public void customException2(CustomException2 exception) {
   //do Something width response body
}

Webclient 得到一个 401 响应,json 正文如下:

{
   "message": "Password is incorrect"
}

我可以创建Mono.error(new CustomException()),但问题是 WebClient 响应体。如果消息是“密码不正确”,我想发送客户端:

用户名或密码不正确

我该怎么做?

【问题讨论】:

  • 你能澄清一下这里的实际和预期结果是什么吗?是否要更改异常处理程序或 Web 客户端代码?
  • @MartinTarjányi 用户发送 ajax 请求,而 Whit 请求参数我向服务器发送请求。我想在失败模式下响应用户不同的答案。所以我想用异常处理程序来做。
  • 有多种方法可以解决这个问题,而您提供的信息太少。您要解决的实际问题是什么,如果您是 webflux 的新手,为什么要So I want do it with Exception Handler。 Webflux 不像 spring boot,你使用 webflux 解决不同的事情。如果你在抛出异常时解释你想要做的更详细的事情。想要登录吗?向客户端返回http状态?提出新要求?

标签: spring spring-boot reactive-programming spring-webflux


【解决方案1】:

请检查以下处理调用的 rest api 调用的错误响应的 API 实现。我假设我们知道 api 的响应,所以我创建了 ResponseDTO 类。

Controller.java

@GetMapping("/webclient/test")
public ResponseDTO testWebclient(@RequestBody RequestDTO requestPayload) {
    String url = "http://localhost:8080/api/write/simple";
    return WebClient.create()
            .post()
            .uri(url)
            .accept(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromObject(requestPayload))
            .retrieve()
            .onStatus(HttpStatus::is4xxClientError, response -> {
                return response.bodyToMono(ResponseDTO.class).flatMap(error -> {
                    return Mono.error(new CustomRuntimeException(error.getMessage(), response.statusCode(), error.getErrorCode()));
                });
            })
            .onStatus(HttpStatus::is5xxServerError, response -> {
                return response.bodyToMono(ResponseDTO.class).flatMap(error -> {
                    return Mono.error(new CustomRuntimeException(error.getMessage(), response.statusCode()));
                });
            })
            .bodyToMono(ResponseDTO.class);
}

ResponseDTO.java

public class ResponseDTO {

    private String message;
    private HttpStatus status;
    private ErrorCode errorCode;
    
    public ResponseDTO(String message, HttpStatus status) {
        this.message = message;
        this.status = status;
    }

    public ResponseDTO(String message, HttpStatus status, ErrorCode errorCode) {
        this.message = message;
        this.status = status;
        this.errorCode = errorCode;
    }
    /** getters **/
}

ErrorCode.java

    public class ErrorCode {
        private String numCode;
        private String txtCode;
        
        /** getters **/
    }

要捕获异常,请在@RestControllerAdvice 的类中添加以下代码 sn-p(希望您已经知道)。

@ExceptionHandler(value = CustomRuntimeException.class)
public final ResponseEntity<ApiResponse> handleCustomRuntimeException(CustomRuntimeException exception) {
    List<ApiSubError> subErrors = Arrays.asList(new ApiSubError(exception.getMessage()));
    ApiResponse response = new ApiErrorResponse(exception.getMessage(), exception.getErrorCode());
    LOG.error("result: {}", response.getResult());
    return new ResponseEntity<>(response, exception.getHttpStatus());
}

【讨论】:

  • 我需要 webclient 响应正文。我想把它发给我的客户。
  • 请检查我在回答中给出的参考资料。
  • 同样的结果。问题是:获取 Webclient 错误响应正文并将其发送给客户端
  • 我已经更新了运行良好的答案。我希望这就是你要找的。为了完成这项工作,我花了 2 个小时,我自己也学会了。
【解决方案2】:

我从未使用过 WebFlux,但我找到了 Add Exception handler for Spring Web Client。看起来您可以通过在 onStatus 处理函数中编写 return Mono.error(new CustomException1()); 来引发异常。根据描述,bodyToMono(Class)方法会抛出异常。

最后,您可以像这样修改您的 ControllerAdvice:

@ExceptionHandler(CustomException.class)
public ResponseEntity<CustomErrorModel> customException(CustomException exception) {
   return new ResponseEntity<>( new CustomErrorModel(), HttpStatus.BAD_REQUEST );
}

正如我所说 - 我没有测试它,但它可能是给你的一个提示。

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 2020-06-09
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多