我正在开发一个Spring Boot项目。我正在使用this post提供的名为ExceptionHandlerController的类检出代码,并在我的项目中尝试了它。它有效,但对于状态代码为400或500系列的错误,我需要包含状态代码。当我在浏览器地址字段中尝试一个简单的无效URL时,视图页面error.jsp会进行渲染,但不会根据模型信息访问状态代码。我已经包含了HttpServletResponse参数来获取状态代码,但代码和消息并未显示在404错误上。 defaultErrorHanddler方法甚至不会触发404错误。我们如何强制该方法触发400和500错误?
ExceptionHandlerController:
@ControllerAdvice
public class ExceptionHandlerController
{
public static final String DEFAULT_ERROR_VIEW = "error";
private static final HashMap<Integer, String> statusCodes = new HashMap<Integer, String>();
static {
statusCodes.put(HttpServletResponse.SC_OK, "OK");
statusCodes.put(HttpServletResponse.SC_CREATED, "Created");
statusCodes.put(HttpServletResponse.SC_ACCEPTED, "Accepted");
statusCodes.put(HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION, "Non-authoritative Information");
statusCodes.put(HttpServletResponse.SC_NO_CONTENT, "No Content");
statusCodes.put(HttpServletResponse.SC_RESET_CONTENT, "Reset Content");
statusCodes.put(HttpServletResponse.SC_PARTIAL_CONTENT, "Partial Content");
statusCodes.put(HttpServletResponse.SC_BAD_REQUEST, "Bad Request");
statusCodes.put(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
statusCodes.put(HttpServletResponse.SC_PAYMENT_REQUIRED, "Payment Required");
statusCodes.put(HttpServletResponse.SC_FORBIDDEN, "Forbidden");
statusCodes.put(HttpServletResponse.SC_NOT_FOUND, "Not Found");
statusCodes.put(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method Not Allowed");
statusCodes.put(HttpServletResponse.SC_NOT_ACCEPTABLE, "Not Acceptable");
statusCodes.put(HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required");
statusCodes.put(HttpServletResponse.SC_REQUEST_TIMEOUT, "Request Timeout");
statusCodes.put(HttpServletResponse.SC_CONFLICT, "Conflict");
statusCodes.put(HttpServletResponse.SC_GONE, "Gone");
statusCodes.put(HttpServletResponse.SC_LENGTH_REQUIRED, "Length Required");
statusCodes.put(HttpServletResponse.SC_PRECONDITION_FAILED, "Precondition Failed");
statusCodes.put(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, "Request entity Too Large");
statusCodes.put(HttpServletResponse.SC_REQUEST_URI_TOO_LONG, "Request-URI Too Long");
statusCodes.put(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
statusCodes.put(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "Requested Range Not Satisfiable");
statusCodes.put(HttpServletResponse.SC_EXPECTATION_FAILED, "Expectation Failed");
statusCodes.put(HttpServletResponse.SC_PRECONDITION_FAILED, "Precondition Required");
statusCodes.put(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
statusCodes.put(HttpServletResponse.SC_NOT_IMPLEMENTED, "Not Implemented");
statusCodes.put(HttpServletResponse.SC_BAD_GATEWAY, "Bad Gateway");
statusCodes.put(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "Service Unavailable");
statusCodes.put(HttpServletResponse.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
statusCodes.put(HttpServletResponse.SC_HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported");
}
@ExceptionHandler(value={Exception.class, RuntimeException.class})
public ModelAndView defaultErrorHanddler(HttpServletRequest request, Exception e, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView(DEFAULT_ERROR_VIEW);
int scode = response.getStatus();
System.out.println("scode: " + scode);
mav.addObject("statuscode", String.valueOf(scode));
mav.addObject("message", statusCodes.get(scode));
mav.addObject("datetime", new Date());
mav.addObject("exception", e);
mav.addObject("url", request.getRequestURL());
return mav;
}
}
的error.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML>
<html>
<head>
<title></title>
...
</head>
<body>
<div class="container">
<h1>Error Details</h1>
<p>Status Code: ${statuscode}</p>
<p>Message: ${message}</p>
<p>TimeStamp: ${datetime}</p>
<p>Exception: ${exception}</p>
<p>URL: ${url}</p>
<p><a href="/">Home Page</a></p>
</div>
</body>
</html>
答案 0 :(得分:2)
或者,您可以使用@ResponseStatus
为方法添加注释,例如:
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = {Exception.class, RuntimeException.class})
public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) {
ModelAndView mav = new ModelAndView(DEFAULT_ERROR_VIEW);
mav.addObject("datetime", new Date());
mav.addObject("exception", e);
mav.addObject("url", request.getRequestURL());
return mav;
}
答案 1 :(得分:1)
将HttpServletResponse
作为参数添加到defaultErrorHandler
方法,然后致电response.setStatusCode
。
修改强>:
如果要将404视为例外,如果使用Spring Boot,请设置spring.mvc.throwExceptionIfNoHandlerFound = true
。如果不使用Spring Boot,请参阅this thread。