【发布时间】:2021-07-27 23:21:27
【问题描述】:
我依靠 spring boot 来处理 500(内部服务器错误)。关注各种链接,其中提到我可以使用以下属性自定义我的网络应用程序
server.error.path=/error
server.error.whitelabel.enabled=false
我还将自定义错误页面控制器编写为:
@Controller
public class GlobalErrorController implements ErrorController {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
log.error("Error occurred!");
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
// handle all the 400 error codes
if (statusCode != null && statusCode % 400 < 100) {
return "error/4xx";
} else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error/500";
}
}
return "error/genericError";
}
}
这个控制器永远不会被调用,我只看到带有控制台错误的服务器错误页面如下:
我可以看到控制台中的 /error 页面明显抛出了错误。以下是错误日志的一部分:
2021-07-27 16:13:28.769 错误 22040 --- [nio-8080-exec-1] o.a.c.c.C.[.[localhost] 175 : 异常处理 ErrorPage[errorCode=0, location=/error]
这里要注意的一点是过滤器中抛出了异常,因为我正在测试应用程序在其中一项服务出现故障时的行为。但是我应该仍然可以使用 /error 控制器获得我期望的页面。
更新: 我做了一些进一步的研究,发现过滤器中抛出的异常不会被全局异常处理程序处理。为了通过 spring 的异常处理程序处理异常,我添加了这个过滤器,它捕获任何其他过滤器引发的异常。代码如下:
@Component
public class ExceptionHandlerFilter extends OncePerRequestFilter {
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (RuntimeException ex) {
log.error("Spring Security Filter Chain Exception:", ex);
resolver.resolveException(request, response, null, ex);
}
}
}
我还为此创建了一个异常处理程序,如下所示:
@ControllerAdvice
public class GlobalExceptionHandler {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(RuntimeException.class)
public ModelAndView handleError(HttpServletRequest req, RuntimeException ex)
{
log.error("Request: " + req.getRequestURL() + " raised " + ex);
ModelAndView mav = new ModelAndView("error/500");
mav.addObject("exception", ex);
mav.addObject("url", req.getRequestURL());
return mav;
}
}
现在的问题是它只显示没有任何内容的空白页面。我期待看到位于 error/500 的自定义错误页面。
【问题讨论】:
标签: spring spring-boot spring-mvc