首页 > 解决方案 > Spring Boot 捕获 thymeleaf 异常时重定向到错误页面

问题描述

当发生 Thymeleaf 错误(即片段不存在)时,我想重定向到我的自定义错误页面 (/error/page)。

我的问题是,如果有任何错误,整个错误页面都会呈现到 Thymeleaf 片段中。

我已经尝试编写自定义错误处理程序和自定义错误控制器,它适用于任何其他异常(重定向到我的自定义错误页面),但在发生 Thymeleaf 错误时则不行。

    @Controller
    public class CustomErrorController implements ErrorController {
    
        private final String ERROR_PATH = "/error";
    
        @RequestMapping(ERROR_PATH)
        public String handleError(HttpServletRequest request) {
            Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
    
            if (status != null) {
                int statusCode = Integer.parseInt(status.toString());
    
                if (statusCode == HttpStatus.NOT_FOUND.value()) {
                    return "redirect:/error/page";
                } else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
                    return "redirect:/error/page";
                }
            }
            // Thymeleaf error -> status code 200 and doesn't work redirect
            return "redirect:/error/page";
        }
    
        @Override
        public String getErrorPath() {
            return ERROR_PATH;
        }
    
        @ModelAttribute(name = "url")
        public String getUrl(@AuthenticationPrincipal User user) {
            return user != null
                    ? "rooms"
                    : "";
        }
    }
    @Controller
    public class DefaultErrorController {
    
        @RequestMapping("/error/page")
        public String handleError() {
            return "errors/error";
        }
    
        @ModelAttribute(name = "url")
        public String getUrl(@AuthenticationPrincipal User user) {
            return user != null
                    ? "rooms"
                    : "";
        }
    
    }

    public class ThymeleafErrorFilter implements Filter {
    
        @Override
        public void init(final FilterConfig filterConfig) {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            try {
                filterChain.doFilter(servletRequest, servletResponse);
            } catch (final NestedServletException nse) {
                if(nse.getCause() instanceof TemplateEngineException) {
                    // redirec to error page
                }
                throw nse;
            }
        }
    
        @Override
        public void destroy() {
        }
    }

应用程序属性:

    ############## ERROR PAGE ################
    server.error.whitelabel.enabled=false
    server.error.path=/error

@EnableAutoConfiguration AppConfig.java

    @Bean
    public FilterRegistrationBean<ThymeleafErrorFilter> thymeleafErrorFilter() {
        var thymeleafErrorFilter = new FilterRegistrationBean<ThymeleafErrorFilter>();
        thymeleafErrorFilter.setName("thymeleafErrorFilter");
        thymeleafErrorFilter.setFilter(new ThymeleafErrorFilter());
        thymeleafErrorFilter.addUrlPatterns("/*");
        return thymeleafErrorFilter;
    }

如果百里香叶碎片不存在。我们在 ThymeleafErrorFilter 中检测到它。在 spring 调用 /error 之后(我们在 CustomErrorController 中捕获它)和在 CustomErrorController 中,状态码是 200,并且重定向不起作用。

标签: javaspringspring-bootexceptionthymeleaf

解决方案


您应该使用 @ControllerAdvise 来处理您的异常并提供一个视图来呈现错误。

看到这个:


@ControllerAdvice
@Slf4j
public class ErrorControllerAdvice {
 

    @ExceptionHandler(StorageException.class)  //handle this exception
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String storageException(final StorageException throwable, final Model model) {
        log.error("Exception during execution of application", throwable);
        model.addAttribute("errorMessage", "Failed to store file"); //custom message to render in HTML
        return "error";  //the html page in resources/templates folder
    }


/// handle other exeptions

风景:

错误.html

<h1> Opps.. Sorry about this. </h1>
<p th:utext="${errorMessage}"></p>

有关更多详细信息,请参阅https://github.com/gtiwari333/spring-boot-blog-app/blob/master/src/main/java/gt/app/web/mvc/ErrorControllerAdvice.java


推荐阅读