使用Spring Web MVC自定义处理405错误

时间:2014-10-07 14:07:54

标签: java spring spring-mvc

在我的应用程序中,我有一些只允许POST的RequestMappings。如果有人碰巧在该特定路径发出GET请求,则会收到容器(Tomcat)提供的405错误页面。我可以在web.xml中创建并定义405错误页面以进行自定义。

我想要的是:任何导致405错误的请求都应该在特定的控制器方法中处理。

我尝试过的事情:

  • 使用"方法= GET"的方法作为所提到的每个映射的对应物。这工作正常,但要求我为每个只允许POST的路径创建一个实际的请求映射和方法。我发现这种不必要的重复和混乱。
  • 全球性的捕捉'方法(requestmapping / *):这不起作用,因为Spring将GET方法作为对仅使用POST指定的路径的错误调用
  • 一个ExceptionHandler-annotated方法来处理类HttpRequestMethodNotSupportedException的异常:这不起作用。似乎Spring在其框架代码中完全抛出并捕获此异常。
  • 在web.xml中指定我自己的405。这并不完美,因为我想要自定义处理而不是静态错误页面。

3 个答案:

答案 0 :(得分:13)

我建议使用Handler Exception Resolver。你可以使用spring DefaultHandlerExceptionResolver。覆盖handleHttpRequestMethodNotSupported()方法并返回自定义的view。这将适用于您的所有应用程序。

效果接近您在选项3中的期望。您的@ExceptionHandler带注释的方法永远不会捕获异常的原因是因为在找到成功的Spring控制器处理程序映射后调用这些ExceptionHandler带注释的方法。但是,在此之前会引发您的异常。

答案 1 :(得分:11)

工作代码:

@ControllerAdvice
public class GlobalExceptionController {

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ModelAndView handleError405(HttpServletRequest request, Exception e) {
        ModelAndView mav = new ModelAndView("/405");
        mav.addObject("exception", e);  
        //mav.addObject("errorcode", "405");
        return mav;
    }
}

在Jsp页面(405.jsp)中:

<div class="http-error-container">
    <h1>HTTP Status 405 - Request Method not Support</h1>
    <p class="message-text">The request method does not support. <a href="<c:url value="/"/>">home page</a>.</p>
</div>

答案 2 :(得分:0)

You can use spring DefaultHandlerExceptionResolver. 
Override handleHttpRequestMethodNotSupported() method and return your customized.
Status Code: 405




protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
            ApiError apiError = ApiError.builder()
                    .status(HttpStatus.METHOD_NOT_ALLOWED)
                    .message(ex.getMessage())
                    .build();
    
            return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
        }

响应结果:

{
    "status": "METHOD_NOT_ALLOWED",
    "message": "Request method 'POST' not supported",
    "errors": null
}