Spring MVC 4与Thymeleaf资源版本化失效问题排查求助
嘿,来解决你的Spring MVC 4 + Thymeleaf资源版本化问题!
你说用th:src="@{/resources/static/js/companyList.js}"看不到带版本的URL,大概率是没配全Spring MVC的资源版本策略,或者漏了关键的过滤器让Thymeleaf和版本化联动。咱们一步步拆解:
1. 先给Spring MVC加上资源版本解析规则
Spring MVC 4本身支持资源版本化,但得先在配置里定义版本策略——不管你用Java Config还是XML,这一步是基础:
如果你用Java Config(推荐):
在你的Web配置类里,给资源映射加上版本解析器:
@Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") // 对外暴露的资源路径前缀 .addResourceLocations("/resources/static/") // 实际文件存放的目录 .resourceChain(true) // 这里用内容哈希生成版本号(文件变了版本号才变),也可以用固定版本比如addFixedVersionStrategy("v1", "/**") .addResolver(new VersionResourceResolver() .addContentVersionStrategy("/**")); } }
如果你用XML配置:
在Spring的mvc配置里加这段:
<mvc:resources mapping="/resources/**" location="/resources/static/"> <mvc:resource-chain> <mvc:resolvers> <mvc:version-resolver> <!-- 对所有资源用内容哈希版本策略 --> <mvc:content-version-strategy patterns="/**"/> </mvc:version-resolver> </mvc:resolvers> </mvc:resource-chain> </mvc:resources>
2. 一定要加ResourceUrlEncodingFilter!
这是很多人容易漏掉的关键一步!这个过滤器会拦截Thymeleaf生成的@{...} URL,自动把资源路径替换成带版本号的格式。没它的话,Thymeleaf根本不知道要给URL加版本。
web.xml里配置:
<filter> <filter-name>resourceUrlEncodingFilter</filter-name> <filter-class>org.springframework.web.servlet.resource.ResourceUrlEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>resourceUrlEncodingFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 拦截所有请求 --> </filter-mapping>
要是用Servlet 3.0+的Java Config注册过滤器:
在你的WebApplicationInitializer里加这段:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // ... 其他初始化代码 @Override protected Filter[] getServletFilters() { return new Filter[]{new ResourceUrlEncodingFilter()}; } }
3. 检查Thymeleaf的配置是否和Spring MVC联动
确保你的Thymeleaf模板引擎用了Spring的标准方言,这样@{...}表达式才能正确解析资源URL:
Java Config示例:
@Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver()); // 必须加这个Spring方言,不然@{...}只会生成普通URL engine.addDialect(new SpringStandardDialect()); return engine; }
XML配置示例:
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"> <property name="templateResolver" ref="templateResolver"/> <property name="additionalDialects"> <set> <bean class="org.thymeleaf.spring4.dialect.SpringStandardDialect"/> </set> </property> </bean>
4. 几个容易踩的坑
- 路径要匹配:你配置的资源映射是
/resources/**对应/resources/static/,那Thymeleaf里应该写@{/resources/js/companyList.js},而不是@{/resources/static/js/companyList.js}——后者会直接找/resources/static/static/js/companyList.js,肯定不对! - 内容哈希版本的缓存问题:第一次加载时Spring会生成文件哈希并缓存,修改文件后可能需要重启应用或者清掉Spring的缓存才会更新版本号。
- 必须用Thymeleaf属性:别直接写
<script src="/resources/js/companyList.js">,一定要用th:src,否则过滤器不会处理这个URL。
验证一下
配置完重启应用,打开页面看源码,应该能看到类似/resources/js/companyList-abc123.js(abc123是文件内容的哈希值)或者/resources/v1/js/companyList.js(如果用固定版本的话)的URL,这就说明生效了!
内容的提问来源于stack exchange,提问作者Anıl Sevici
相关产品推荐
相关产品推荐

