我有一个Spring Boot应用程序,使用Thymeleaf 3作为应用程序页面的模板引擎。我们使用 spring-boot-starter-thymeleaf 提供的默认配置,以及 src / main / resources / templates 文件夹下的HTML Thymeleaf模板。
现在我们想使用Thymeleaf生成一些javascript文件,使用新的javascript模板模式。这些javascript模板可以位于相同的HTML模板文件夹中,也可以位于另一个模板文件夹中(例如: src / main / resources / jstemplates )。
我不知道是否有办法添加此配置而不更改 spring-boot-starter-thymeleaf 提供的默认配置中的任何内容,或者我必须创建一个一切都完整配置。
我已尝试使用以下配置的第一个选项,该选项适用于javascript模板,但html模板不再适用。
配置:
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter
implements ApplicationContextAware {
private static final String UTF8 = "UTF-8";
@Autowired
private SpringTemplateEngine templateEngine;
@Autowired
private ThymeleafProperties properties;
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean
public ThymeleafViewResolver javascriptThymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(this.templateEngine);
resolver.setCharacterEncoding(UTF8);
resolver.setContentType("application/javascript");
resolver.setViewNames(new String[] {".js"});
resolver.setCache(this.properties.isCache());
return resolver;
}
@Bean
public SpringResourceTemplateResolver javascriptTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("classpath:/jstemplates/");
resolver.setSuffix(".js");
resolver.setTemplateMode(TemplateMode.JAVASCRIPT);
resolver.setCharacterEncoding(UTF8);
return resolver;
}
}
测试javascript控制器:
@Controller
public class JavascriptController {
@RequestMapping(method = RequestMethod.GET, value = "/test.js")
public String testjs() {
return "test";
}
}
根页面的控制器:
@Controller
public class MainController {
@RequestMapping(method = RequestMethod.GET, value = "/")
public String index(Model model) {
return "index";
}
}
src / main / resources / jstemplates 文件夹中有 test.js 文件。如果我尝试了网址http://localhost:8080/test.js,它会按预期工作。但是,如果我尝试,例如,主网址(http://localhost:8080/)失败,并出现以下错误:
引起:java.io.FileNotFoundException:类路径资源 [jstemplates / index.js]无法打开,因为它不存在
应该寻找 templates / index.html ,因此似乎 javascriptTemplateResolver 会覆盖或优先于默认值,而不会回退到它。
有没有办法添加与默认Thymeleaf配置集成的其他模板模式支持,或者我需要从头开始配置所有内容?
答案 0 :(得分:3)
经过一些调试后我终于找到了解决方案。如果模板确实存在,那么 SpringResourceTemplateResolver 似乎不会默认检查。在我的示例配置中,第一个模板解析器是为javascript模板配置的解析器,它创建了一个 View ,而不先查看模板是否存在。
要解决此问题,必须将模板 checkExistence 属性设置为 true 。例如:
@Bean
public SpringResourceTemplateResolver javascriptTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("classpath:/jstemplates/");
resolver.setSuffix(".js");
resolver.setTemplateMode(TemplateMode.JAVASCRIPT);
resolver.setCharacterEncoding(UTF8);
resolver.setCheckExistence(true);
return resolver;
}
我在这个配置中看到的唯一问题是,如果我们创建一个与html视图同名的js视图,它将始终获得javascript视图。
修改强>
为了解决最后一个问题,我对配置进行了一些更改:
最终配置如下:
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter
implements ApplicationContextAware {
private static final String UTF8 = "UTF-8";
@Autowired
private ThymeleafProperties properties;
@Autowired
private TemplateEngine templateEngine;
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean
public ThymeleafViewResolver javascriptThymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(this.templateEngine);
resolver.setCharacterEncoding(UTF8);
resolver.setContentType("application/javascript");
resolver.setViewNames(new String[] {"*.js"});
resolver.setCache(this.properties.isCache());
return resolver;
}
@Bean
public SpringResourceTemplateResolver javascriptTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(this.applicationContext);
resolver.setPrefix("classpath:/templates/js/");
resolver.setTemplateMode(TemplateMode.JAVASCRIPT);
resolver.setCharacterEncoding(UTF8);
resolver.setCheckExistence(true);
resolver.setCacheable(this.properties.isCache());
return resolver;
}
}
样本控制器:
@Controller
public class JavascriptController {
@RequestMapping(method = RequestMethod.GET, value = "/js/test.js")
public String testjs() {
return "test.js";
}
}
HTML视图控制器保持不变。