我目前抛出一个自定义异常-RequestValidationException
。
ExceptionHandler
>
类strong>:@RestControllerAdvice
@Slf4j
public class RestExceptionHandler {
@ExceptionHandler(value = RequestValidationException.class)
@ResponseStatus(HttpStatus.PRECONDITION_FAILED)
public Mono<HttpValidationError> handleRequestValidationException(RequestValidationException exception) {
log.error("Received exception: ", exception);
List<String> loc = new ArrayList<>();
loc.add(exception.getMessage());
ValidationError validationError = ValidationError.builder()
.loc(loc)
.msg(exception.getMessage())
.build();
List<ValidationError> errorMessages = new ArrayList<>();
errorMessages.add(validationError);
return Mono.just(HttpValidationError.builder().detail(errorMessages).build());
}
<RequestValidationException
>类strong>:public class RequestValidationException extends RuntimeException {
public static final HttpStatus statusCode = HttpStatus.PRECONDITION_FAILED;
public RequestValidationException(String text) {
super(text);
}
public HttpStatus getStatusCode() {
return statusCode;
}
}
当抛出exception
时,我想要以下response
:
Code: 412
{
"detail": [
{
"loc": [
"No ID found to update. Please add an ID"
],
"msg": "No ID found to update. Please add an ID",
"type": null
}
]
}
我收到的是:
{
"error_code": 500,
"message": "No ID found to update. Please add an ID"
}
我检查了应用程序日志,没有地方被调用RestExceptionHandler
。它只记录error
:
"level":"ERROR","logger":"c.a.c.c.c.AbstractController","thread":"boundedElastic-1","message":"Controller exception","stack":"<#384d845f> c.a.c.a.e.RequestValidationException
我似乎不明白这段代码有什么问题。有人能指出我可能遗漏了什么吗?谢谢。
我只能让它与AbstractErrorWebExceptionHandler
的实现一起工作,如下所示(对不起,kotlin代码):
@Component
@Order(-2)
class GlobalExceptionHandler(errorAttributes: ErrorAttributes,
resources: WebProperties.Resources,
applicationContext: ApplicationContext,
serverCodecConfigurer: ServerCodecConfigurer) : AbstractErrorWebExceptionHandler(errorAttributes, resources, applicationContext) {
companion object {
private val logger = KotlinLogging.logger {}
private const val HTTP_STATUS_KEY = "status"
private const val MESSAGE_KEY = "message"
private const val ERRORS_KEY = "errors"
}
init {
setMessageWriters(serverCodecConfigurer.writers)
}
override fun setMessageWriters(messageWriters: MutableList<HttpMessageWriter<*>>?) {
super.setMessageWriters(messageWriters)
}
override fun getRoutingFunction(errorAttributes: ErrorAttributes?): RouterFunction<ServerResponse> {
return RouterFunctions.route({ true }) { request ->
val error: Throwable = getError(request)
logger.error("Handling: ", error)
val errorProperties = getErrorAttributes(request, ErrorAttributeOptions.defaults())
when (error) {
is WebExchangeBindException -> {
....
}
else -> {
...
}
}
ServerResponse.status(HttpStatus.valueOf(errorProperties[HTTP_STATUS_KEY] as Int))
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(errorProperties)
}
}
}
在Java中是这样的:
@Component
@Order(-2)
public class GlobalExceptionHandler extends AbstractErrorWebExceptionHandler {
private static final String HTTP_STATUS_KEY = "status";
private static final String MESSAGE_KEY = "message";
private static final String ERRORS_KEY = "errors";
public GlobalExceptionHandler(ErrorAttributes errorAttributes, Resources resources, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) {
super(errorAttributes, resources, applicationContext);
this.setMessageWriters(serverCodecConfigurer.getWriters());
}
public final void setMessageWriters(List messageWriters) {
super.setMessageWriters(messageWriters);
}
protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
Map<String, Object> errorPropertiesMap = getErrorAttributes(request,
ErrorAttributeOptions.defaults());
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(errorPropertiesMap));
}
}
您可以在https://www.baeldung.com/spring-webflux-errors#global查看更多详细信息。
我犯了一个非常小的错误,用AbstractController
类扩展controller
,这导致了这个问题。把它去掉,问题就解决了。