Spring boot 和 Thymeleaf - 再次热交换模板和资源
Spring boot and Thymeleaf - Hot swap templates and resources once again
我尝试了在这里和文档中找到的所有提示和技巧,但仍然没有成功。我有 Spring webapp with Thymeleaf。当我在 IDEA 中调用更新时,资源和模板不会重新加载(它没有说明要重新加载)。然后我可以疯狂地在浏览器中按 ctrl+f5,更改就没有了。
一切都在一个 Java class 中配置,如下所示:
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
我的文件夹结构现在看起来像
this,但我也尝试将没有"static"文件夹的资源或webapp/resources.
ResourceHandlerRegistry:
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/img/");
registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/");
registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/");
}
我在两个 application.properties:
中都指定了 cache=false
spring.thymeleaf.cache=false
并在提到的 MvcConfig class:
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(false);
return templateResolver;
}
根据 SO 上的一些答案,我添加了对 devtools 的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>1.4.1.RELEASE</version>
<optional>true</optional>
</dependency>
还是不行。有人说要添加 maven boot plugin with addResources=true,所以我做了:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.1.RELEASE</version>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
我想我的想法设置正确,因为当我调用更新时,我的 Java classes 会立即重新加载。只有资源和 html 文件不是,我必须为此重新启动服务器。实际上 *.html 文件没什么大不了的,但是在每次 css 和 js 的小改动后重新启动服务器会让我的速度变慢很多,因为我花了将近 15 个小时才弄清楚出了什么问题, 开始真的很沮丧。
任何帮助将不胜感激。
好的,所以我找到了针对我的具体案例的答案。问题根本不在我的应用程序或其配置中(好吧..可能)。我没有使用 Tomcat 8.5.5,而是切换回 Tomcat 7。现在一切正常。有人知道为什么吗?
我花了一些时间在这上面,最后在这里我将解释我是如何让它工作的。
谷歌搜索你可能会发现一些信息:
- Spring Boot hot swap
- SO - Spring Boot + Jetty & hot deployment
- SO - Netbeans 8 won't reload static Thymeleaf files
我最初的方法是禁用缓存并添加 Spring 开发工具:
Spring开机application.properties
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.prefix=/templates/
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
但是使用上面的代码片段是不够的,因为热插拔仅在创建项目时完成(Intellij Idea 中的 CTRL + F9)。这是因为 默认模板解析器是 class 基于路径的 ,这就是需要重新编译的原因。
一个可行的解决方案 是通过使用基于文件系统的解析器覆盖 defaultTemplateResolver
:
application.properties
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.templates_root=src/main/resources/templates/
申请class
@SpringBootApplication
public class MyApplication {
@Autowired
private ThymeleafProperties properties;
@Value("${spring.thymeleaf.templates_root:}")
private String templatesRoot;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public ITemplateResolver defaultTemplateResolver() {
FileTemplateResolver resolver = new FileTemplateResolver();
resolver.setSuffix(properties.getSuffix());
resolver.setPrefix(templatesRoot);
resolver.setTemplateMode(properties.getMode());
resolver.setCacheable(properties.isCache());
return resolver;
}
}
我发现这个解决方案是最佳的,因为它允许您外部化配置并使用不同的配置文件(dev、prod 等),同时通过 只需按 F5 即可重新加载更改 :)
这是我使用 IntelliJ IDEA (2018.3) 的设置,保存更改后重新加载 HTML:
在application.properties中:
spring.resources.static-locations = classpath:/resources/static
spring.resources.cache.period = 0
在pom.xml中设置<addResources>true</addResources>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
菜单 Run
=> Edit Configurations
(IntelliJ IDEA)
帧停用:Update resources
@Luke 我的解决方案很简单:
HTML / CSS / JS 在 Spring 中自动重新加载 Thymeleaf 可以简单且无错误,仅在 IntelliJ 中测试过。
将此添加到 Maven,使用 ${spring.version} var 或替换为您的版本:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring.version}</version>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
添加到html的header:
<script src="http://localhost:35729/livereload.js"></script>
使用 IntelliJ 时:
我尝试了在这里和文档中找到的所有提示和技巧,但仍然没有成功。我有 Spring webapp with Thymeleaf。当我在 IDEA 中调用更新时,资源和模板不会重新加载(它没有说明要重新加载)。然后我可以疯狂地在浏览器中按 ctrl+f5,更改就没有了。
一切都在一个 Java class 中配置,如下所示:
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
我的文件夹结构现在看起来像 this,但我也尝试将没有"static"文件夹的资源或webapp/resources.
ResourceHandlerRegistry:
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/img/");
registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/");
registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/");
}
我在两个 application.properties:
中都指定了 cache=falsespring.thymeleaf.cache=false
并在提到的 MvcConfig class:
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(false);
return templateResolver;
}
根据 SO 上的一些答案,我添加了对 devtools 的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>1.4.1.RELEASE</version>
<optional>true</optional>
</dependency>
还是不行。有人说要添加 maven boot plugin with addResources=true,所以我做了:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.1.RELEASE</version>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
我想我的想法设置正确,因为当我调用更新时,我的 Java classes 会立即重新加载。只有资源和 html 文件不是,我必须为此重新启动服务器。实际上 *.html 文件没什么大不了的,但是在每次 css 和 js 的小改动后重新启动服务器会让我的速度变慢很多,因为我花了将近 15 个小时才弄清楚出了什么问题, 开始真的很沮丧。
任何帮助将不胜感激。
好的,所以我找到了针对我的具体案例的答案。问题根本不在我的应用程序或其配置中(好吧..可能)。我没有使用 Tomcat 8.5.5,而是切换回 Tomcat 7。现在一切正常。有人知道为什么吗?
我花了一些时间在这上面,最后在这里我将解释我是如何让它工作的。 谷歌搜索你可能会发现一些信息:
- Spring Boot hot swap
- SO - Spring Boot + Jetty & hot deployment
- SO - Netbeans 8 won't reload static Thymeleaf files
我最初的方法是禁用缓存并添加 Spring 开发工具:
Spring开机application.properties
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.prefix=/templates/
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
但是使用上面的代码片段是不够的,因为热插拔仅在创建项目时完成(Intellij Idea 中的 CTRL + F9)。这是因为 默认模板解析器是 class 基于路径的 ,这就是需要重新编译的原因。
一个可行的解决方案 是通过使用基于文件系统的解析器覆盖 defaultTemplateResolver
:
application.properties
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.templates_root=src/main/resources/templates/
申请class
@SpringBootApplication
public class MyApplication {
@Autowired
private ThymeleafProperties properties;
@Value("${spring.thymeleaf.templates_root:}")
private String templatesRoot;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public ITemplateResolver defaultTemplateResolver() {
FileTemplateResolver resolver = new FileTemplateResolver();
resolver.setSuffix(properties.getSuffix());
resolver.setPrefix(templatesRoot);
resolver.setTemplateMode(properties.getMode());
resolver.setCacheable(properties.isCache());
return resolver;
}
}
我发现这个解决方案是最佳的,因为它允许您外部化配置并使用不同的配置文件(dev、prod 等),同时通过 只需按 F5 即可重新加载更改 :)
这是我使用 IntelliJ IDEA (2018.3) 的设置,保存更改后重新加载 HTML:
在application.properties中:
spring.resources.static-locations = classpath:/resources/static spring.resources.cache.period = 0
在pom.xml中设置
<addResources>true</addResources>
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <addResources>true</addResources> </configuration> </plugin>
菜单
Run
=>Edit Configurations
(IntelliJ IDEA)
帧停用:Update resources
@Luke 我的解决方案很简单:
HTML / CSS / JS 在 Spring 中自动重新加载 Thymeleaf 可以简单且无错误,仅在 IntelliJ 中测试过。
将此添加到 Maven,使用 ${spring.version} var 或替换为您的版本:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring.version}</version>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
添加到html的header:
<script src="http://localhost:35729/livereload.js"></script>
使用 IntelliJ 时: