@PostMapping("/reverse")
public Mono<String> reverse(@RequestHeader HttpHeaders headers,
@RequestBody RQTextMessage message) {
message.setLocalDateTime(LocalDateTime.now());
log.info("reverse message:{}", message);
return textMessageWebClient.post()
.uri("/reverse")
.headers(clientHeaders -> {
clientHeaders.addAll(headers);
})
.bodyValue(message)
.retrieve()
.bodyToMono(String.class)
// ==================== 1. HTTP 响应异常 (收到响应但状态码错误) ====================
.onErrorResume(WebClientResponseException.class, ex -> {
return handleHttpError(ex);
})
// ==================== 2. 网络连接异常 (连接阶段失败) ====================
// 2.1 DNS 解析失败
.onErrorResume(UnknownHostException.class, ex -> {
return handleNetworkError("域名解析失败", ex);
})
// 2.2 路由不可达 (防火墙/网络配置问题)
.onErrorResume(NoRouteToHostException.class, ex -> {
return handleNetworkError("网络不可达", ex);
})
// 2.3 连接超时 (服务器在规定时间内未响应)
.onErrorResume(ConnectTimeoutException.class, ex -> {
return handleNetworkError("连接超时", ex);
})
// 2.4 连接被拒绝 (服务宕机/端口未开放)
.onErrorResume(ConnectException.class, ex -> {
return handleNetworkError("连接被拒绝", ex);
})
// ==================== 3. 响应超时异常 (连接成功但响应超时) ====================
// 3.1 整体响应超时 (由 responseTimeout 配置触发)
.onErrorResume(TimeoutException.class, ex -> {
return handleTimeoutError("响应超时", ex);
})
// 3.2 读取超时 (由 ReadTimeoutHandler 触发,如未配置则不会触发)
.onErrorResume(ReadTimeoutException.class, ex -> {
return handleTimeoutError("读取超时", ex);
})
// ==================== 4. 其他未知异常 (兜底) ====================
.onErrorResume(Exception.class, ex -> {
return handleUnknownError(ex);
});
}
/**
* 处理 HTTP 响应错误
*/
private Mono<String> handleHttpError(WebClientResponseException ex) {
log.error("HTTP响应错误: {} - {}", ex.getStatusCode(), ex.getResponseBodyAsString());
return Mono.error(new BusinessException(
ex.getRawStatusCode(),
"远程服务返回错误: " + ex.getStatusCode()));
}
/**
* 处理网络连接错误
*/
private Mono<String> handleNetworkError(String reason, Exception ex) {
log.warn("{}: {}", reason, ex.getMessage());
return Mono.error(new BusinessException(
HttpStatus.SERVICE_UNAVAILABLE.value(),
"网络连接失败: " + reason));
}
/**
* 处理超时错误
*/
private Mono<String> handleTimeoutError(String reason, Exception ex) {
log.warn("{}: {}", reason, ex.getMessage());
return Mono.error(new BusinessException(
HttpStatus.GATEWAY_TIMEOUT.value(),
"请求超时: " + reason));
}
/**
* 处理未知错误
*/
private Mono<String> handleUnknownError(Exception ex) {
log.error("未知异常: {}", ex.getClass().getName(), ex);
return Mono.error(new BusinessException(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"系统内部错误"));
}