我需要在全局异常处理程序中使用 NoHandlerFoundException 异常处理程序。
我已经通过从扩展的 ResponseEntityExceptionHandler 类重写 MethodArgumentNotValidException 处理程序来使用它。
现在,在运行应用程序时,我收到此异常。
我使用 Argument Not valid handler 方法来处理请求正文中缺少的字段。
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate \[org.springframework.web.servlet.HandlerExceptionResolver\]: Factory method 'handlerExceptionResolver' threw exception with message: Ambiguous @ExceptionHandler method mapped for \[class org.springframework.web.bind.MethodArgumentNotValidException\]: {protected org.springframework.http.ResponseEntity com.kroger.iwt.coreservice.exception.handler.GlobalExceptionHandler.handleMethodArgumentNotValid(org.springframework.web.bind.MethodArgumentNotValidException,org.springframework.http.HttpHeaders,org.springframework.http.HttpStatusCode,org.springframework.web.context.request.WebRequest), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception}
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ NoHandlerFoundException.class })
@ResponseBody
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<ErrorListResponse> notFound(final NoHandlerFoundException exception) {
log.error("{} {}", 404, exception.getMessage());
ErrorListResponse errorListResponse = errorResponse("Request URI Not Found", exception);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorListResponse);
}
// @Override
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
List<FieldError> errors = ex.getBindingResult().getFieldErrors();
List<ErrorListResponse.ErrorDetails> errorDetails = new ArrayList<>();
for (FieldError fieldError : errors) {
ErrorListResponse.ErrorDetails error = new ErrorListResponse.ErrorDetails();
error.setReason(fieldError.getDefaultMessage());
error.setCode("BAD_REQUEST");
error.setDatetime(new DateTimeResponse(Instant.now().toString(), "America/New_York"));
errorDetails.add(error);
}
ErrorListResponse errorResponse = new ErrorListResponse();
errorResponse.setErrors(errorDetails);
log.error("{} {}", 400, "Multiple fields are invalid");
return new ResponseEntity(errorResponse, HttpStatus.BAD_REQUEST);
}
}
当您扩展
ResponseEntityExceptionHandler
类并重写其方法时,您不应使用 @ExceptionHandler
注释。
否则 Spring 的
org.springframework.web.servlet.HandlerExceptionResolver
会为同一个异常类找到多个处理程序并报告错误。
这对于仅处理这些异常的方法也有效。即使有不同的名字。此处列出了例外情况:
@ExceptionHandler({
HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class,
HttpMediaTypeNotAcceptableException.class,
MissingPathVariableException.class,
MissingServletRequestParameterException.class,
MissingServletRequestPartException.class,
ServletRequestBindingException.class,
MethodArgumentNotValidException.class,
HandlerMethodValidationException.class,
NoHandlerFoundException.class,
NoResourceFoundException.class,
AsyncRequestTimeoutException.class,
ErrorResponseException.class,
MaxUploadSizeExceededException.class,
ConversionNotSupportedException.class,
TypeMismatchException.class,
HttpMessageNotReadableException.class,
HttpMessageNotWritableException.class,
MethodValidationException.class,
BindException.class
})
解决方案
从处理与
@ExceptionHandler
中相同的异常的方法中删除 ResponseEntityExceptionHandler
注释。