/** * A variation on {@link #getForLookupPath(String)} that accepts a full request * URL path (i.e. including context and servlet path) and returns the full request * URL path to expose for public use. * @param request the current request * @param requestUrl the request URL path to resolve * @return the resolved public URL path, or {@code null} if unresolved */ @Nullable public final String getForRequestUrl(HttpServletRequest request, String requestUrl) { int prefixIndex = getLookupPathIndex(request); int suffixIndex = getEndPathIndex(requestUrl); if (prefixIndex >= suffixIndex) { return null; } String prefix = requestUrl.substring(0, prefixIndex); String suffix = requestUrl.substring(suffixIndex); String lookupPath = requestUrl.substring(prefixIndex, suffixIndex); String resolvedLookupPath = getForLookupPath(lookupPath); return (resolvedLookupPath != null ? prefix + resolvedLookupPath + suffix : null); }
/** * A {@link ResourceUrlProvider} bean for use with the MVC dispatcher. * @since 4.1 */ @Bean public ResourceUrlProvider mvcResourceUrlProvider() { ResourceUrlProvider urlProvider = new ResourceUrlProvider(); UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); if (pathHelper != null) { urlProvider.setUrlPathHelper(pathHelper); } PathMatcher pathMatcher = getPathMatchConfigurer().getPathMatcher(); if (pathMatcher != null) { urlProvider.setPathMatcher(pathMatcher); } return urlProvider; }
/** * A transformer can use this method when a resource being transformed * contains links to other resources. Such links need to be replaced with the * public facing link as determined by the resource resolver chain (e.g. the * public URL may have a version inserted). * @param resourcePath the path to a resource that needs to be re-written * @param request the current request * @param resource the resource being transformed * @param transformerChain the transformer chain * @return the resolved URL, or {@code} if not resolvable */ @Nullable protected String resolveUrlPath(String resourcePath, HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) { if (resourcePath.startsWith("/")) { // full resource path ResourceUrlProvider urlProvider = findResourceUrlProvider(request); return (urlProvider != null ? urlProvider.getForRequestUrl(request, resourcePath) : null); } else { // try resolving as relative path return transformerChain.getResolverChain().resolveUrlPath( resourcePath, Collections.singletonList(resource)); } }
@Override public void onApplicationEvent(ContextRefreshedEvent event) { if (isAutodetect()) { this.handlerMap.clear(); detectResourceHandlers(event.getApplicationContext()); if (!this.handlerMap.isEmpty()) { this.autodetect = false; } } }
@Test // SPR-16296 public void getForLookupPathShouldNotFailIfPathContainsDoubleSlashes() { // given ResourceResolver mockResourceResolver = mock(ResourceResolver.class); when(mockResourceResolver.resolveUrlPath(any(), any(), any())).thenReturn("some-path"); ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.getResourceResolvers().add(mockResourceResolver); ResourceUrlProvider provider = new ResourceUrlProvider(); provider.getHandlerMap().put("/some-pattern/**", handler); // when String lookupForPath = provider.getForLookupPath("/some-pattern/some-lib//some-resource"); // then assertEquals("/some-pattern/some-path", lookupForPath); }
protected AbstractInitializrController(InitializrMetadataProvider metadataProvider, ResourceUrlProvider resourceUrlProvider) { this.metadataProvider = metadataProvider; this.linkTo = (link) -> { String result = resourceUrlProvider.getForLookupPath(link); return (result != null) ? result : link; }; }
private ResourceUrlProvider createResourceUrlProvider(List<ResourceResolver> resolvers) { ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass()))); handler.setResourceResolvers(resolvers); ResourceUrlProvider urlProvider = new ResourceUrlProvider(); urlProvider.setHandlerMap(Collections.singletonMap("/resources/**", handler)); return urlProvider; }
private int getLookupPathIndex(HttpServletRequest request) { UrlPathHelper pathHelper = getUrlPathHelper(); String requestUri = pathHelper.getRequestUri(request); String lookupPath = pathHelper.getLookupPathForRequest(request); return requestUri.indexOf(lookupPath); }
@Test // SPR-12647 public void bestPatternMatch() throws Exception { ResourceHttpRequestHandler otherHandler = new ResourceHttpRequestHandler(); otherHandler.setLocations(this.locations); Map<String, VersionStrategy> versionStrategyMap = new HashMap<>(); versionStrategyMap.put("/**", new ContentVersionStrategy()); VersionResourceResolver versionResolver = new VersionResourceResolver(); versionResolver.setStrategyMap(versionStrategyMap); List<ResourceResolver> resolvers = new ArrayList<>(); resolvers.add(versionResolver); resolvers.add(new PathResourceResolver()); otherHandler.setResourceResolvers(resolvers); this.handlerMap.put("/resources/*.css", otherHandler); this.urlProvider.setHandlerMap(this.handlerMap); String url = this.urlProvider.getForLookupPath("/resources/foo.css"); assertEquals("/resources/foo-e36d2e05253c6c7085a91522ce43a0b4.css", url); }
@Test // SPR-12592 @SuppressWarnings("resource") public void initializeOnce() throws Exception { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.setServletContext(new MockServletContext()); context.register(HandlerMappingConfiguration.class); context.refresh(); ResourceUrlProvider urlProviderBean = context.getBean(ResourceUrlProvider.class); assertThat(urlProviderBean.getHandlerMap(), Matchers.hasKey("/resources/**")); assertFalse(urlProviderBean.isAutodetect()); }
@Bean public ResourceUrlProvider resourceUrlProvider() { return new ResourceUrlProvider(); } }
if (getPathMatcher().match(pattern, lookupPath)) { matchingPatterns.add(pattern); Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath); matchingPatterns.sort(patternComparator); for (String pattern : matchingPatterns) { String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath); String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping)); ResourceHttpRequestHandler handler = this.handlerMap.get(pattern);
@Nullable public String resolveUrlPath(String url) { if (this.resourceUrlProvider == null) { logger.trace("ResourceUrlProvider not available via request attribute " + "ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR"); return null; } if (this.indexLookupPath != null && url.startsWith(this.prefixLookupPath)) { int suffixIndex = getEndPathIndex(url); String suffix = url.substring(suffixIndex); String lookupPath = url.substring(this.indexLookupPath, suffixIndex); lookupPath = this.resourceUrlProvider.getForLookupPath(lookupPath); if (lookupPath != null) { return this.prefixLookupPath + lookupPath + suffix; } } return null; }
@Override public void onApplicationEvent(ContextRefreshedEvent event) { if (isAutodetect()) { this.handlerMap.clear(); detectResourceHandlers(event.getApplicationContext()); if (!this.handlerMap.isEmpty()) { this.autodetect = false; } } }
private ResourceUrlProvider createUrlProvider(List<ResourceResolver> resolvers) { ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass()))); handler.setResourceResolvers(resolvers); ResourceUrlProvider urlProvider = new ResourceUrlProvider(); urlProvider.setHandlerMap(Collections.singletonMap("/resources/**", handler)); return urlProvider; }
private void initLookupPath(ResourceUrlProvider urlProvider) { this.resourceUrlProvider = urlProvider; if (this.indexLookupPath == null) { UrlPathHelper pathHelper = this.resourceUrlProvider.getUrlPathHelper(); String requestUri = pathHelper.getRequestUri(this); String lookupPath = pathHelper.getLookupPathForRequest(this); this.indexLookupPath = requestUri.lastIndexOf(lookupPath); this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath); if ("/".equals(lookupPath) && !"/".equals(requestUri)) { String contextPath = pathHelper.getContextPath(this); if (requestUri.equals(contextPath)) { this.indexLookupPath = requestUri.length(); this.prefixLookupPath = requestUri; } } } }
/** * A {@link ResourceUrlProvider} bean for use with the MVC dispatcher. * @since 4.1 */ @Bean public ResourceUrlProvider mvcResourceUrlProvider() { ResourceUrlProvider urlProvider = new ResourceUrlProvider(); UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); if (pathHelper != null) { urlProvider.setUrlPathHelper(pathHelper); } PathMatcher pathMatcher = getPathMatchConfigurer().getPathMatcher(); if (pathMatcher != null) { urlProvider.setPathMatcher(pathMatcher); } return urlProvider; }
if (getPathMatcher().match(pattern, lookupPath)) { matchingPatterns.add(pattern); Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath); matchingPatterns.sort(patternComparator); for (String pattern : matchingPatterns) { String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath); String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping)); ResourceHttpRequestHandler handler = this.handlerMap.get(pattern);
/** * A variation on {@link #getForLookupPath(String)} that accepts a full request * URL path (i.e. including context and servlet path) and returns the full request * URL path to expose for public use. * @param request the current request * @param requestUrl the request URL path to resolve * @return the resolved public URL path, or {@code null} if unresolved */ @Nullable public final String getForRequestUrl(HttpServletRequest request, String requestUrl) { int prefixIndex = getLookupPathIndex(request); int suffixIndex = getEndPathIndex(requestUrl); if (prefixIndex >= suffixIndex) { return null; } String prefix = requestUrl.substring(0, prefixIndex); String suffix = requestUrl.substring(suffixIndex); String lookupPath = requestUrl.substring(prefixIndex, suffixIndex); String resolvedLookupPath = getForLookupPath(lookupPath); return (resolvedLookupPath != null ? prefix + resolvedLookupPath + suffix : null); }
@Nullable public String resolveUrlPath(String url) { if (this.resourceUrlProvider == null) { logger.trace("ResourceUrlProvider not available via request attribute " + "ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR"); return null; } if (this.indexLookupPath != null && url.startsWith(this.prefixLookupPath)) { int suffixIndex = getEndPathIndex(url); String suffix = url.substring(suffixIndex); String lookupPath = url.substring(this.indexLookupPath, suffixIndex); lookupPath = this.resourceUrlProvider.getForLookupPath(lookupPath); if (lookupPath != null) { return this.prefixLookupPath + lookupPath + suffix; } } return null; }