如何在ControllerAdvice spring boot中捕获freemarker TemplateException?

问题描述 投票:0回答:1

尝试找出如何在 ControllerAdvice 中捕获 TemplateException 以便能够记录异常。

这是配置:

@Configuration
public class FreeMarkerConfig {

    @Bean
    public ViewResolver viewResolver() {
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
        resolver.setCache(true);
        resolver.setPrefix("classpath:/templates/");
        resolver.setSuffix(".ftlh");
        return resolver;
    }

    @Bean
    public FreeMarkerConfigurer freemarkerConfig() {
        FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
        freeMarkerConfigurer.setTemplateLoaderPath("classpath:/templates/");

        Properties settings = new Properties();
        settings.setProperty(freemarker.template.Configuration.TEMPLATE_EXCEPTION_HANDLER_KEY, "rethrow");
        freeMarkerConfigurer.setFreemarkerSettings(settings);
        return freeMarkerConfigurer;
    }
}
@ControllerAdvice
public class CustomExceptionHandler {
    private static final Logger logger = LogManager.getLogger(CustomExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    public String handleException(final HttpServletRequest request, final Exception e) {
        String incidentId = logException(request, e);
        return "redirect:/error?incident-id=" + incidentId;
    }
    @ExceptionHandler(TemplateException.class)
    public ResponseEntity<Object> handleTemplEx(Exception e,
                                         HttpServletRequest request, HttpServletResponse response) {
        logException(request, e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }
}

CustomExceptionHandler 无法捕获 TemplateException,我只是在控制台中收到错误,例如:

18:16:39 |错误 | http-nio-8080-exec-1 | http-nio-8080-exec-1 | freemarker.runtime | 免费标记执行 FreeMarker 模板时出错 freemarker.core.InvalidReferenceException:以下内容已计算为 null 或缺失: ==>articleTagIndice1s [在模板“themes/article.ftlh”第 7 行第 20 列]

发现了几个类似的主题,但没有一个对我有用: 解决方案1解决方案2

spring freemarker exceptionhandler
1个回答
0
投票

感谢@lane.maxwell提到的文章我找到了解决方案。因此,工作配置和处理程序如下:

@Configuration
public class FreeMarkerConfig {
@Bean
public FreeMarkerConfigurer freemarkerConfig() throws TemplateException, IOException {
    FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
    freeMarkerConfigurer.setTemplateLoaderPath("classpath:/templates/");

    freemarker.template.Configuration configuration = freeMarkerConfigurer.createConfiguration();
    configuration.setTemplateExceptionHandler(new TemplateExceptionHandlerImpl());
    freeMarkerConfigurer.setConfiguration(configuration);

    return freeMarkerConfigurer;
}

TemplateExceptionHandlerImpl:

public class TemplateExceptionHandlerImpl implements TemplateExceptionHandler {
    private static final Logger logger = LogManager.getLogger(ArticleCategoryIndexRestController.class);

    public void handleTemplateException(TemplateException te, Environment env, java.io.Writer out) throws TemplateException {
        try {
            String incidentId = UUID.randomUUID().toString();
            logger.error(String.format("=== INCIDENT ID %s ===", incidentId));
            logger.error("FREEMARKER TemplateException");
            logger.error("Template: " + env.getMainTemplate().getName());
            logger.error("Exception: ", te);
            out.write("<div class=\"alert alert-danger\" role=\"alert\">");
            out.write("Something went wrong, INCIDENT ID: " + incidentId);
            out.write("</div>");
        } catch (IOException e) {
            throw new TemplateException("Something went wrong", env);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.