[英]How to catch HTTP 405 "Method Not Allowed" exception using @ExceptionHandler?
我創建了一個 REST 應用程序並添加了一個類來處理異常:
@RestControllerAdvice(basePackages = "com.foxminded.university.api.controller")
public class ApiGlobalExceptionHandler extends ResponseEntityExceptionHandler {
private static final String API_UNHANDLED_EXCEPTION = "REST API reached unhandled exception: %s";
private static final HttpStatus internalServerError = HttpStatus.INTERNAL_SERVER_ERROR;
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handle(Exception e) {
ExceptionDetail exceptionDetail = new ExceptionDetail(
String.format(API_UNHANDLED_EXCEPTION, e.getMessage()),
internalServerError,
ZonedDateTime.now(ZoneId.systemDefault()));
return new ResponseEntity<Object>(exceptionDetail, internalServerError);
}
@Override
public ResponseEntity<Object> handleTypeMismatch(
TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
ExceptionDetail exceptionDetail = new ExceptionDetail(
String.format(API_UNHANDLED_EXCEPTION, ex.getMessage()),
internalServerError,
ZonedDateTime.now(ZoneId.systemDefault()));
return new ResponseEntity<Object>(exceptionDetail, internalServerError);
}
@Override
public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException e, HttpHeaders headers,
HttpStatus status, WebRequest request) {
ExceptionDetail exceptionDetail = new ExceptionDetail(
String.format(API_UNHANDLED_EXCEPTION, e.getMessage()),
internalServerError,
ZonedDateTime.now(ZoneId.systemDefault()),
e.getBindingResult().getFieldErrors());
return new ResponseEntity<Object>(exceptionDetail, internalServerError);
}
}
當我通過郵遞員發送錯誤的帖子請求時 http://localhost:8080/api/groups/jkjk 而不是 http://localhost:8080/api/groups
它向我拋出一個異常,我在調試時無法捕獲初始化,無論是在 ApiGlobalExceptionHandler 類中還是在 ResponseEntityExceptionHandler 類中:
{
"timestamp": 1604171144423,
"status": 405,
"error": "Method Not Allowed",
"message": "",
"path": "/api/groups/jkjk"
}
我可以捕獲的所有其他異常。 如何捕獲此異常以添加自定義處理?
您只需要在其簽名中添加一個新方法 with MethodNotAllowedException
。
@ExceptionHandler(value = MethodNotAllowedException.class)
public ResponseEntity<Object> handleMethodNotAllowedExceptionException(MethodNotAllowedException ex) {
return buildResponseEntity(HttpStatus.METHOD_NOT_ALLOWED, null, null, ex.getMessage(), null);
}
private ResponseEntity<Object> buildResponseEntity(HttpStatus status, HttpHeaders headers, Integer internalCode, String message, List<Object> errors) {
ResponseBase response = new ResponseBase() //A generic ResponseBase class
.success(false)
.message(message)
.resultCode(internalCode != null ? internalCode : status.value())
.errors(errors != null
? errors.stream().filter(Objects::nonNull).map(Objects::toString).collect(Collectors.toList())
: null);
return new ResponseEntity<>((Object) response, headers, status);
}
您可以根據需要自定義buildResponseEntity
。
更新
我重新審視了我的答案,因為它不符合您的要求。 所以,它是這樣的:
我為接受GET
的方法發送 post 請求。 這將觸發不支持的請求方法“POST” ,如下所示。
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.Looking up handler method for path /v1/user/profile/1 org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.Resolving exception from handler [null]:org.springframework.web.HttpRequestMethodNotSupportedException:不支持請求方法“POST”
在這種情況下,不需要添加@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
。
事實上,如果你這樣做,會拋出以下錯誤(因為它已經被處理了),
java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.HttpRequestMethodNotSupportedException]:....
因此,解決方案將是:
@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
return buildResponseEntity(HttpStatus.METHOD_NOT_ALLOWED, headers, null, ex.getMessage(), Arrays.asList(""));
}
我在這里找到了解釋自定義處理 405 錯誤與 Spring Web MVC
它說The reason your @ExceptionHandler annotated method never catches your exception is because these ExceptionHandler annotated methods are invoked after a successful Spring controller handler mapping is found. However, your exception is raised before that.
The reason your @ExceptionHandler annotated method never catches your exception is because these ExceptionHandler annotated methods are invoked after a successful Spring controller handler mapping is found. However, your exception is raised before that.
解決方案不是從 ResponseEntityExceptionHandler 類擴展,而是從 DefaultHandlerExceptionResolver 擴展並覆蓋它 handleHttpRequestMethodNotSupported 方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.