我试图根据HTTP状态代码显示自定义错误页面。我所做的是在ErrorController
中实现Spring的CustomErrorController
接口,但是似乎Spring Boot无法识别它。
我已按照本教程进行操作:https://www.baeldung.com/spring-boot-custom-error-page(第3.1节)。
我已经读到,首先,您需要摆脱著名的Spring默认的Whitelabel Error Page。所以我这样做了:
@SpringBootApplication(exclude = { ErrorMvcAutoConfiguration.class })
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
这似乎可行,因为不再出现Whitelabel错误页面,但是现在当发生错误时,出现Apache Tomcat错误页面(包括堆栈跟踪的丑陋页面)而不是我的。
然后我就这样实现了CustomErrorController
:
@Controller
@RequestMapping("/error")
public class CustomErrorController implements ErrorController {
@RequestMapping
public String handleError(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (statusCode != null) {
// Specific error page
return "redirect:/error/" + statusCode;
}
// Global error page
return "error/error";
}
@Override
public String getErrorPath() {
return "/error";
}
@GetMapping("/404")
public String notFoundErrorPage() {
return "error/404";
}
// Other error codes mapping methods
}
我正在使用Thymeleaf,并且错误视图位于src/main/resources/views/error
下,其中每个特定的错误页面名称都遵循建议的<error_code>.html
格式,因此,例如404错误将具有{{1 }}页面。
到目前为止,我对其他应用程序视图的解析没有任何问题。实际上,我已经配置了Spring Security以在发生访问被拒绝并且错误页面正确显示的情况下调用404.html
端点。
/error/403
也会发生同样的情况,发生内部服务器异常时会调用此方法,因为我还实现了以下/error/500
方法:
@ControllerAdvice @ExceptionHandler
因此,如果这些端点中的每一个都单独工作,那么为什么如果Spring引发错误,@ControllerAdvice
@Log4j2
public class GlobalDefaultExceptionHandler {
@ExceptionHandler(Exception.class)
public String defaultErrorHandler(Exception exception) throws Exception {
if (AnnotationUtils.findAnnotation(exception.getClass(), ResponseStatus.class) != null) {
throw exception;
}
log.catching(exception);
return "redirect:/error/500";
}
}
方法就永远不会被调用?
谢谢。
答案 0 :(得分:1)
似乎您的GlobalDefaultExceptionHandler
正在预先捕获所有异常。这就是为什么从未调用handleError
的原因。
您的其他端点正常工作,因为您直接调用它们-正如您所描述的那样。
我建议使用@ControllerAdvice
处理特定的异常,让您的CustomErrorController
实现处理所有尚未处理的异常。春季启动会将它们包装在Http Status 500中的NestedServletException
内。您可以使用以下方法在handleError
内找到根本原因:
Object exception = request.getAttribute("javax.servlet.error.exception");
if (String.valueOf(exception) != null) {
log.info("Nested Exception: " + String.valueOf(exception));
}
检查这些答案以获取有关订购以及Spring Boot中错误工作流程的更多信息: