我正在构建一个 SpringBoot 应用程序,它从数据库加载国际化消息。 (遵循本教程)
从此,我必须创建一个 ThymeleafConfiguration 类并设置一个 SpringTemplateEngine Bean。本教程仅给出了有关此配置的粗略想法(仅配置了消息源,但没有配置其他模板引擎配置),因此它破坏了我的控制器页面渲染(控制器现在返回字符串而不是视图)。
我正在尝试配置 TemplateEngine 的其余部分(例如 TemplateResolver,我认为这是渲染不正确的原因),但是,我不知道如何正确执行此操作 [我不断收到“模板解析期间发生错误(模板:“ServletContext资源[/templates/login.html]”)“消息]。
如何正确配置SpringTemplateEngine?
到目前为止我的配置:
@Configuration
public class ThymeleafConfiguration implements WebMvcConfigurer, ApplicationContextAware{
private ApplicationContext applicationContext;
@Autowired
private DatabaseMessageSource databaseMessageSource;
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(thymeleafTemplateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
@Bean
public SpringTemplateEngine thymeleafTemplateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.setTemplateEngineMessageSource(databaseMessageSource);
return engine;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
控制器类:
@Controller
public class ApplicationController {
@RequestMapping("/home")
public String home() {
return "/home.html";
}
@RequestMapping("/core/index")
public String index() {
return "/core/index.html";
}
@RequestMapping("/login")
public String login() {
return "login";
}
问题在于
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/templates/"); // Here!!!
resolver.setSuffix(".html");
return resolver;
}
由于模板位于 src/main/resources 中,因此必须指向类路径,如下所示:
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("classpath:/templates/"); // It works after adding 'classpath:'
resolver.setSuffix(".html");
return resolver;
}
此外,从接口到实现类有一些变化,但不会影响结果。
另一个例子,以防有人想要工作参考:
@Configuration
public class ThymeleafConfig implements InitializingBean {
public static final String TEMPLATE_LOCATION = "classpath:/thymeleaf/templates/email/";
protected static final Logger logger = CustomLoggerFactory.getLogger();
@Autowired
private ApplicationContext applicationContext;
@Bean
public SpringTemplateEngine emailTemplateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(htmlTemplateResolver());
templateEngine.setTemplateResolver(textTemplateResolver());
return templateEngine;
}
private SpringResourceTemplateResolver htmlTemplateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setOrder(Integer.valueOf(1));
templateResolver.setPrefix(TEMPLATE_LOCATION);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.toString());
templateResolver.setCacheable(false);
templateResolver.setCheckExistence(true);
return templateResolver;
}
private SpringResourceTemplateResolver textTemplateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setOrder(Integer.valueOf(2));
templateResolver.setPrefix(TEMPLATE_LOCATION);
templateResolver.setSuffix(".txt");
templateResolver.setTemplateMode(TemplateMode.TEXT);
templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.toString());
templateResolver.setCacheable(false);
templateResolver.setCheckExistence(true);
return templateResolver;
}
@Override
public void afterPropertiesSet() throws Exception {
// this just prints the templates found
String path = TEMPLATE_LOCATION;
ClassPathResource resource = new ClassPathResource(path);
try (InputStream inputStream = resource.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
logger.info("Found the following templates in " + path);
String line;
while ((line = reader.readLine()) != null) {
logger.info(line);
}
} catch (Exception e) {
logger.error("Caught Exception listing email templates:" + e.toString());
}
}
}