尝试找出如何在 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 列]
感谢@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);
}
}
}