Webflux WebClient中如何自定义异常?
Posted
技术标签:
【中文标题】Webflux WebClient中如何自定义异常?【英文标题】:How do custom exception in 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状态?提出新要求?
【参考方案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 );
正如我所说 - 我没有测试它,但它可能是给你的一个提示。
【讨论】:
以上是关于Webflux WebClient中如何自定义异常?的主要内容,如果未能解决你的问题,请参考以下文章