/** * Add a resource handler for serving static resources based on the specified * URL path patterns. The handler will be invoked for every incoming request * that matches to one of the specified path patterns. * <p>Patterns like {@code "/static/**"} or {@code "/css/{filename:\\w+\\.css}"} * are allowed. See {@link org.springframework.web.util.pattern.PathPattern} * for more details on the syntax. * @return a {@link ResourceHandlerRegistration} to use to further configure * the registered resource handler */ public ResourceHandlerRegistration addResourceHandler(String... patterns) { ResourceHandlerRegistration registration = new ResourceHandlerRegistration(this.resourceLoader, patterns); this.registrations.add(registration); return registration; }
@Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/images/**").addResourceLocations("/images/"); } }
for (String pathPattern : registration.getPathPatterns()) { ResourceWebHandler handler = registration.getRequestHandler(); handler.getResourceTransformers().forEach(transformer -> { if (transformer instanceof ResourceTransformerSupport) {
/** * Whether a resource handler has already been registered for the given path pattern. */ public boolean hasMappingForPattern(String pathPattern) { for (ResourceHandlerRegistration registration : this.registrations) { if (Arrays.asList(registration.getPathPatterns()).contains(pathPattern)) { return true; } } return false; }
CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer(); this.registration.setCacheControl(CacheControl.maxAge(3600, TimeUnit.MILLISECONDS)) .resourceChain(false) .addResolver(cachingResolver) .addResolver(versionResolver)
@Test public void resourceChainWithoutCaching() throws Exception { this.registration.resourceChain(false); ResourceWebHandler handler = getHandler("/resources/**"); List<ResourceResolver> resolvers = handler.getResourceResolvers(); assertThat(resolvers, Matchers.hasSize(2)); assertThat(resolvers.get(0), Matchers.instanceOf(WebJarsResourceResolver.class)); assertThat(resolvers.get(1), Matchers.instanceOf(PathResourceResolver.class)); List<ResourceTransformer> transformers = handler.getResourceTransformers(); assertThat(transformers, Matchers.hasSize(0)); }
@Test public void cacheControl() { assertThat(getHandler("/resources/**").getCacheControl(), Matchers.nullValue()); this.registration.setCacheControl(CacheControl.noCache().cachePrivate()); assertThat(getHandler("/resources/**").getCacheControl().getHeaderValue(), Matchers.equalTo(CacheControl.noCache().cachePrivate().getHeaderValue())); }
/** * Whether a resource handler has already been registered for the given path pattern. */ public boolean hasMappingForPattern(String pathPattern) { for (ResourceHandlerRegistration registration : this.registrations) { if (Arrays.asList(registration.getPathPatterns()).contains(pathPattern)) { return true; } } return false; }
@Test public void resourceChain() throws Exception { ResourceUrlProvider resourceUrlProvider = Mockito.mock(ResourceUrlProvider.class); this.registry.setResourceUrlProvider(resourceUrlProvider); ResourceResolver mockResolver = Mockito.mock(ResourceResolver.class); ResourceTransformerSupport mockTransformer = Mockito.mock(ResourceTransformerSupport.class); this.registration.resourceChain(true).addResolver(mockResolver).addTransformer(mockTransformer); ResourceWebHandler handler = getHandler("/resources/**"); List<ResourceResolver> resolvers = handler.getResourceResolvers(); assertThat(resolvers.toString(), resolvers, Matchers.hasSize(4)); assertThat(resolvers.get(0), Matchers.instanceOf(CachingResourceResolver.class)); CachingResourceResolver cachingResolver = (CachingResourceResolver) resolvers.get(0); assertThat(cachingResolver.getCache(), Matchers.instanceOf(ConcurrentMapCache.class)); assertThat(resolvers.get(1), Matchers.equalTo(mockResolver)); assertThat(resolvers.get(2), Matchers.instanceOf(WebJarsResourceResolver.class)); assertThat(resolvers.get(3), Matchers.instanceOf(PathResourceResolver.class)); List<ResourceTransformer> transformers = handler.getResourceTransformers(); assertThat(transformers, Matchers.hasSize(2)); assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class)); assertThat(transformers.get(1), Matchers.equalTo(mockTransformer)); Mockito.verify(mockTransformer).setResourceUrlProvider(resourceUrlProvider); }
/** * Return a handler mapping with the mapped resource handlers; or {@code null} in case * of no registrations. */ protected AbstractHandlerMapping getHandlerMapping() { if (this.registrations.isEmpty()) { return null; } Map<String, WebHandler> urlMap = new LinkedHashMap<>(); for (ResourceHandlerRegistration registration : this.registrations) { for (String pathPattern : registration.getPathPatterns()) { ResourceWebHandler handler = registration.getRequestHandler(); handler.setContentTypeResolver(this.contentTypeResolver); try { handler.afterPropertiesSet(); handler.afterSingletonsInstantiated(); } catch (Exception ex) { throw new BeanInitializationException("Failed to init ResourceHttpRequestHandler", ex); } urlMap.put(pathPattern, handler); } } SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); handlerMapping.setOrder(this.order); handlerMapping.setUrlMap(urlMap); return handlerMapping; }
@Before public void setup() { this.registry = new ResourceHandlerRegistry(new GenericApplicationContext()); this.registration = this.registry.addResourceHandler("/resources/**"); this.registration.addResourceLocations("classpath:org/springframework/web/reactive/config/"); }
/** * Add a resource handler for serving static resources based on the specified * URL path patterns. The handler will be invoked for every incoming request * that matches to one of the specified path patterns. * * <p>Patterns like {@code "/static/**"} or {@code "/css/{filename:\\w+\\.css}"} * are allowed. See {@link org.springframework.util.AntPathMatcher} for more * details on the syntax. * @return A {@link ResourceHandlerRegistration} to use to further * configure the registered resource handler */ public ResourceHandlerRegistration addResourceHandler(String... patterns) { ResourceHandlerRegistration registration = new ResourceHandlerRegistration(this.applicationContext, patterns); this.registrations.add(registration); return registration; }
@Test public void resourceChainWithVersionResolver() throws Exception { VersionResourceResolver versionResolver = new VersionResourceResolver() .addFixedVersionStrategy("fixed", "/**/*.js") .addContentVersionStrategy("/**"); this.registration.resourceChain(true).addResolver(versionResolver) .addTransformer(new AppCacheManifestTransformer()); ResourceWebHandler handler = getHandler("/resources/**"); List<ResourceResolver> resolvers = handler.getResourceResolvers(); assertThat(resolvers.toString(), resolvers, Matchers.hasSize(4)); assertThat(resolvers.get(0), Matchers.instanceOf(CachingResourceResolver.class)); assertThat(resolvers.get(1), Matchers.sameInstance(versionResolver)); assertThat(resolvers.get(2), Matchers.instanceOf(WebJarsResourceResolver.class)); assertThat(resolvers.get(3), Matchers.instanceOf(PathResourceResolver.class)); List<ResourceTransformer> transformers = handler.getResourceTransformers(); assertThat(transformers, Matchers.hasSize(3)); assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class)); assertThat(transformers.get(1), Matchers.instanceOf(CssLinkResourceTransformer.class)); assertThat(transformers.get(2), Matchers.instanceOf(AppCacheManifestTransformer.class)); }
@Test public void resourceHandlerMapping() throws Exception { delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer)); doAnswer(invocation -> { ResourceHandlerRegistry registry = invocation.getArgument(0); registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static"); return null; }).when(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class)); delegatingConfig.resourceHandlerMapping(); verify(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class)); verify(webFluxConfigurer).configurePathMatching(any(PathMatchConfigurer.class)); }
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); }