Cache expiration and versioning of resource file work correctly on all pages. But flows seem to ignore Spring MVC configuration.
A working example:
resource files have versioning
With Spring Web Flow:
resource files are missing versioning
In WebMvcConfig class:
@Configuration
@EnableCaching
@ConfigurationProperties("message")
public class WebMvcConfig implements WebMvcConfigurer, ServletContextAware {
...
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
.resourceChain(false)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
.addTransformer(new CssLinkResourceTransformer());
}
@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
return new ResourceUrlEncodingFilter();
}
...
}
WebConfigClass:
@Configuration
@EnableWebMvc
public class WebFlowConfig extends AbstractFlowConfiguration {
@Autowired
private ViewResolver viewResolver;
@Autowired
private RequestDataInterceptor requestDataInterceptor;
@Autowired
private LocalValidatorFactoryBean validator;
// WEB FLOW
@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry()).addFlowExecutionListener(new SecurityFlowExecutionListener(), "*").build();
}
@Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder(flowBuilderServices()).setBasePath("/WEB-INF/flows/").addFlowLocationPattern("/**/*-flow.xml").build();
}
@Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder().setViewFactoryCreator(mvcViewFactoryCreator()).setValidator(validator).setDevelopmentMode(true).setConversionService(getDefaultConversionService()).build();
}
private DefaultConversionService getDefaultConversionService() {
final DefaultConversionService service = new DefaultConversionService();
final FormattingConversionService delegateConversionService = (FormattingConversionService) service.getDelegateConversionService();
delegateConversionService.removeConvertible(String.class, Number.class);
delegateConversionService.addConverterFactory(new StringToNumberConverterFactory());
delegateConversionService.addConverter(new TrimStringConverter());
return service;
}
// MVC
@Bean
public FlowHandlerMapping flowHandlerMapping() {
final FlowHandlerMapping mapping = new FlowHandlerMapping();
mapping.setOrder(0);
mapping.setFlowRegistry(this.flowRegistry());
mapping.setInterceptors(requestDataInterceptor);
return mapping;
}
@Bean
public FlowHandlerAdapter flowHandlerAdapter() {
final FlowHandlerAdapter adapter = new FlowHandlerAdapter();
adapter.setFlowExecutor(this.flowExecutor());
adapter.setSaveOutputToFlashScopeOnRedirect(true);
return adapter;
}
@Bean
public MvcViewFactoryCreator mvcViewFactoryCreator() {
final MvcViewFactoryCreator factoryCreator = new MvcViewFactoryCreator();
factoryCreator.setViewResolvers(Lists.newArrayList(this.viewResolver));
factoryCreator.setUseSpringBeanBinding(true);
return factoryCreator;
}
}
In security config:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
public void configure(final WebSecurity web) {
web.ignoring().antMatchers("/resources/**");
}
...
}
In jsp files (including flow):
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
...
<!-- jQuery -->
<script type="text/javascript" src="<c:url value="/resources/scripts/libs/jquery-3.3.1.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/scripts/jquery-validation/jquery.validate.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/scripts/jquery-numbers/jquery.number.min.js"/>"></script>
...
Any ideas on how to apply versioning of static assets on flows?
my way to deal with it:
<spring:eval expression="@applicationProperties.resourcesVersion" var="resourcesVersion"/>
<head>
<style type="text/css" media='screen,print'>
@import url("<c:url value="/resources/css-framework/css/tools.css?v=${resourcesVersion}" />");
</style>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring.js?v=${resourcesVersion}" />"></script>
</head>
ApplicationProperties:
@Named
public class ApplicationProperties {
....
private Long resourcesVersion = System.currentTimeMillis();
public Long getResourcesVersion() {
return resourcesVersion;
}
}