Polish static resource handling mechanism
- ResourceResolver and ResourceResolverChain now have a consistent API with regard to method names and terminology. - ResourceResolver and ResourceResolverChain now accept List<? extends Resource> instead of List<Resource> for simplified programmatic use. - Improved Javadoc across the package. - Formatted code to align with standards. - Removed all references to ResourceUrlPathTranslator. Issue: SPR-10933
This commit is contained in:
parent
cd13b4882c
commit
3d18cfeab6
|
@ -28,30 +28,32 @@ import org.springframework.util.Assert;
|
|||
|
||||
|
||||
/**
|
||||
* A default implementation of
|
||||
* {@link org.springframework.web.servlet.resource.ResourceResolverChain ResourceResolverChain}
|
||||
* for invoking a list of {@link ResourceResolver}s.
|
||||
* A default implementation of {@link ResourceResolverChain} for invoking a list
|
||||
* of {@link ResourceResolver}s.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
class DefaultResourceResolverChain implements ResourceResolverChain {
|
||||
|
||||
private static Log logger = LogFactory.getLog(DefaultResourceResolverChain.class);
|
||||
private static final Log logger = LogFactory.getLog(DefaultResourceResolverChain.class);
|
||||
|
||||
private final List<ResourceResolver> resolvers = new ArrayList<ResourceResolver>();
|
||||
|
||||
private int index = -1;
|
||||
|
||||
|
||||
public DefaultResourceResolverChain(List<ResourceResolver> resolvers) {
|
||||
this.resolvers.addAll((resolvers != null) ? resolvers : new ArrayList<ResourceResolver>());
|
||||
public DefaultResourceResolverChain(List<? extends ResourceResolver> resolvers) {
|
||||
if (resolvers != null) {
|
||||
this.resolvers.addAll(resolvers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath, List<Resource> locations) {
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations) {
|
||||
ResourceResolver resolver = getNextResolver();
|
||||
if (resolver == null) {
|
||||
return null;
|
||||
|
@ -68,14 +70,14 @@ class DefaultResourceResolverChain implements ResourceResolverChain {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String resolveUrlPath(String resourcePath, List<Resource> locations) {
|
||||
public String resolvePublicUrlPath(String resourcePath, List<? extends Resource> locations) {
|
||||
ResourceResolver resolver = getNextResolver();
|
||||
if (resolver == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
logBefore(resolver);
|
||||
String urlPath = resolver.getPublicUrlPath(resourcePath, locations, this);
|
||||
String urlPath = resolver.resolvePublicUrlPath(resourcePath, locations, this);
|
||||
logAfter(resolver, urlPath);
|
||||
return urlPath;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.springframework.util.DigestUtils;
|
|||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* A {@code ResourceResolver} that resolves request paths containing an additional
|
||||
* MD5 hash in the file name.
|
||||
|
@ -48,18 +47,19 @@ import org.springframework.util.StringUtils;
|
|||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class FingerprintResourceResolver implements ResourceResolver {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FingerprintResourceResolver.class);
|
||||
|
||||
private final Pattern pattern = Pattern.compile("-(\\S*)\\.");
|
||||
private static final Pattern pattern = Pattern.compile("-(\\S*)\\.");
|
||||
|
||||
|
||||
@Override
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath,
|
||||
List<Resource> locations, ResourceResolverChain chain) {
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
|
||||
Resource resolved = chain.resolveResource(request, requestPath, locations);
|
||||
if (resolved != null) {
|
||||
|
@ -82,13 +82,13 @@ public class FingerprintResourceResolver implements ResourceResolver {
|
|||
return baseResource;
|
||||
}
|
||||
else {
|
||||
logger.debug("Potential resource found for ["+requestPath+"], but fingerprint doesn't match.");
|
||||
logger.debug("Potential resource found for [" + requestPath + "], but fingerprint doesn't match.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String extractHash(String path) {
|
||||
Matcher matcher = this.pattern.matcher(path);
|
||||
Matcher matcher = pattern.matcher(path);
|
||||
if (matcher.find()) {
|
||||
String match = matcher.group(1);
|
||||
return match.contains("-") ? match.substring(match.lastIndexOf("-") + 1) : match;
|
||||
|
@ -104,19 +104,20 @@ public class FingerprintResourceResolver implements ResourceResolver {
|
|||
return DigestUtils.md5DigestAsHex(content);
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Failed to calculate hash on resource [" + resource.toString()+"]");
|
||||
logger.error("Failed to calculate hash for resource [" + resource + "]");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicUrlPath(String resourceUrlPath, List<Resource> locations, ResourceResolverChain chain) {
|
||||
String baseUrl = chain.resolveUrlPath(resourceUrlPath, locations);
|
||||
public String resolvePublicUrlPath(String resourceUrlPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
String baseUrl = chain.resolvePublicUrlPath(resourceUrlPath, locations);
|
||||
if (StringUtils.hasText(baseUrl)) {
|
||||
Resource original = chain.resolveResource(null, resourceUrlPath, locations);
|
||||
String hash = calculateHash(original);
|
||||
return StringUtils.stripFilenameExtension(baseUrl)
|
||||
+ "-" + hash + "." + StringUtils.getFilenameExtension(baseUrl);
|
||||
return StringUtils.stripFilenameExtension(baseUrl) + "-" + hash + "."
|
||||
+ StringUtils.getFilenameExtension(baseUrl);
|
||||
}
|
||||
return baseUrl;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.springframework.core.io.Resource;
|
|||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class GzipResourceResolver implements ResourceResolver {
|
||||
|
@ -48,8 +49,8 @@ public class GzipResourceResolver implements ResourceResolver {
|
|||
|
||||
|
||||
@Override
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath,
|
||||
List<Resource> locations, ResourceResolverChain chain) {
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
|
||||
Resource resource = chain.resolveResource(request, requestPath, locations);
|
||||
if ((resource == null) || !isGzipAccepted(request)) {
|
||||
|
@ -75,8 +76,9 @@ public class GzipResourceResolver implements ResourceResolver {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getPublicUrlPath(String resourceUrlPath, List<Resource> locations, ResourceResolverChain chain) {
|
||||
return chain.resolveUrlPath(resourceUrlPath, locations);
|
||||
public String resolvePublicUrlPath(String resourceUrlPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
return chain.resolvePublicUrlPath(resourceUrlPath, locations);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* A simple {@code ResourceResolver} that tries to find a resource under the given
|
||||
* locations matching to the request path.
|
||||
|
@ -35,6 +34,7 @@ import org.springframework.core.io.Resource;
|
|||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class PathResourceResolver implements ResourceResolver {
|
||||
|
@ -43,18 +43,18 @@ public class PathResourceResolver implements ResourceResolver {
|
|||
|
||||
|
||||
@Override
|
||||
public Resource resolveResource(HttpServletRequest request,
|
||||
String requestPath, List<Resource> locations, ResourceResolverChain chain) {
|
||||
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
return getResource(requestPath, locations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicUrlPath(String resourceUrlPath, List<Resource> locations, ResourceResolverChain chain) {
|
||||
public String resolvePublicUrlPath(String resourceUrlPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
return (getResource(resourceUrlPath, locations) != null) ? resourceUrlPath : null;
|
||||
}
|
||||
|
||||
private Resource getResource(String path, List<Resource> locations) {
|
||||
private Resource getResource(String path, List<? extends Resource> locations) {
|
||||
for (Resource location : locations) {
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.resource;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
@ -35,22 +36,24 @@ import java.util.List;
|
|||
* it causes only actually modified resources to be reloaded.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class PrefixResourceResolver implements ResourceResolver {
|
||||
|
||||
private final String prefix;
|
||||
|
||||
|
||||
public PrefixResourceResolver(String prefix) {
|
||||
Assert.hasText(prefix, "resource path prefix should not be null");
|
||||
Assert.hasText(prefix, "prefix must not be null or empty");
|
||||
this.prefix = prefix.startsWith("/") ? prefix : "/" + prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource resolveResource(HttpServletRequest request,
|
||||
String requestPath, List<Resource> locations, ResourceResolverChain chain) {
|
||||
public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
|
||||
if(requestPath.startsWith(this.prefix)) {
|
||||
if (requestPath.startsWith(this.prefix)) {
|
||||
requestPath = requestPath.substring(this.prefix.length());
|
||||
}
|
||||
|
||||
|
@ -58,8 +61,10 @@ public class PrefixResourceResolver implements ResourceResolver {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getPublicUrlPath(String resourceUrlPath, List<Resource> locations, ResourceResolverChain chain) {
|
||||
String baseUrl = chain.resolveUrlPath(resourceUrlPath, locations);
|
||||
public String resolvePublicUrlPath(String resourceUrlPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain) {
|
||||
String baseUrl = chain.resolvePublicUrlPath(resourceUrlPath, locations);
|
||||
return this.prefix + (baseUrl.startsWith("/") ? baseUrl : "/" + baseUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ import java.util.Map;
|
|||
|
||||
|
||||
/**
|
||||
* A central component aware of Spring MVC handler mappings for serving static
|
||||
* resources that provides methods to determine the public URL path clients
|
||||
* should to access static resource.
|
||||
* A central component for serving static resources that is aware of Spring MVC
|
||||
* handler mappings and provides methods to determine the public URL path that
|
||||
* a client should use to access a static resource.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.1
|
||||
|
@ -45,7 +45,6 @@ public class PublicResourceUrlProvider implements ApplicationListener<ContextRef
|
|||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
|
||||
private UrlPathHelper pathHelper = new UrlPathHelper();
|
||||
|
||||
private PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
@ -154,8 +153,8 @@ public class PublicResourceUrlProvider implements ApplicationListener<ContextRef
|
|||
* URL path to expose for public use.
|
||||
*
|
||||
* @param request the current request
|
||||
* @param requestUrl the request URL path to translate
|
||||
* @return the translated resource URL path or {@code null}
|
||||
* @param requestUrl the request URL path to resolve
|
||||
* @return the resolved public URL path or {@code null} if unresolved
|
||||
*/
|
||||
public final String getForRequestUrl(HttpServletRequest request, String requestUrl) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
@ -181,19 +180,18 @@ public class PublicResourceUrlProvider implements ApplicationListener<ContextRef
|
|||
/**
|
||||
* Compare the given path against configured resource handler mappings and
|
||||
* if a match is found use the {@code ResourceResolver} chain of the matched
|
||||
* {@code ResourceHttpRequestHandler} to determine the URL path to expose for
|
||||
* {@code ResourceHttpRequestHandler} to resolve the URL path to expose for
|
||||
* public use.
|
||||
*
|
||||
* <p>It is expected the given path is what Spring MVC would use for request
|
||||
* mapping purposes, i.e. excluding context and servlet path portions.
|
||||
*
|
||||
* @param lookupPath the look path to check
|
||||
*
|
||||
* @return the resolved URL path or {@code null} if unresolved
|
||||
* @param lookupPath the lookup path to check
|
||||
* @return the resolved public URL path or {@code null} if unresolved
|
||||
*/
|
||||
public final String getForLookupPath(String lookupPath) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Checking lookup path=" + lookupPath);
|
||||
logger.debug("Checking lookup path: " + lookupPath);
|
||||
}
|
||||
for (String pattern : this.handlerMap.keySet()) {
|
||||
if (!getPathMatcher().match(pattern, lookupPath)) {
|
||||
|
@ -207,7 +205,7 @@ public class PublicResourceUrlProvider implements ApplicationListener<ContextRef
|
|||
}
|
||||
ResourceHttpRequestHandler handler = this.handlerMap.get(pattern);
|
||||
ResourceResolverChain chain = handler.createResourceResolverChain();
|
||||
String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations());
|
||||
String resolved = chain.resolvePublicUrlPath(pathWithinMapping, handler.getLocations());
|
||||
if (resolved == null) {
|
||||
throw new IllegalStateException("Failed to get public resource URL path for " + pathWithinMapping);
|
||||
}
|
||||
|
|
|
@ -23,9 +23,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* An interceptor that exposes the
|
||||
* {@link PublicResourceUrlProvider ResourceUrlPathTranslator}
|
||||
* instance it is configured with as a request attribute.
|
||||
* An interceptor that exposes the {@link PublicResourceUrlProvider} instance it
|
||||
* is configured with as a request attribute.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.1
|
||||
|
@ -33,8 +32,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
public class PublicResourceUrlProviderExposingInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
/**
|
||||
* Name of request attribute that holds
|
||||
* {@link PublicResourceUrlProvider ResourceUrlPathTranslator}.
|
||||
* Name of the request attribute that holds the {@link PublicResourceUrlProvider}.
|
||||
*/
|
||||
public static final String RESOURCE_URL_PROVIDER_ATTR = PublicResourceUrlProvider.class.getName().toString();
|
||||
|
||||
|
|
|
@ -22,45 +22,46 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* A strategy for matching a request to a server-side resource. Provides a mechanism
|
||||
* for resolving an incoming request to an actual
|
||||
* {@link org.springframework.core.io.Resource} and also for obtaining the public
|
||||
* URL path clients should use when requesting the resource.
|
||||
* A strategy for resolving a request to a server-side resource.
|
||||
*
|
||||
* <p>Provides mechanisms for resolving an incoming request to an actual
|
||||
* {@link org.springframework.core.io.Resource} and for obtaining the public
|
||||
* URL path that clients should use when requesting the resource.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*
|
||||
* @see org.springframework.web.servlet.resource.ResourceResolverChain
|
||||
*/
|
||||
public interface ResourceResolver {
|
||||
|
||||
/**
|
||||
* Resolve the input request and request path to a {@link Resource} that
|
||||
* Resolve the supplied request and request path to a {@link Resource} that
|
||||
* exists under one of the given resource locations.
|
||||
*
|
||||
* @param request the current request
|
||||
* @param requestPath the portion of the request path to use
|
||||
* @param locations locations where to look for resources
|
||||
* @param chain a chain with other resolvers to delegate to
|
||||
*
|
||||
* @param locations the locations to search in when looking up resources
|
||||
* @param chain the chain of resolvers to delegate to
|
||||
* @return the resolved resource or {@code null} if unresolved
|
||||
*/
|
||||
Resource resolveResource(HttpServletRequest request, String requestPath,
|
||||
List<Resource> locations, ResourceResolverChain chain);
|
||||
Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations,
|
||||
ResourceResolverChain chain);
|
||||
|
||||
/**
|
||||
* Get the externally facing public URL path for clients to use to access the
|
||||
* resource located at the resource URL path.
|
||||
* Resolve the externally facing <em>public</em> URL path for clients to use
|
||||
* to access the resource that is located at the given <em>internal</em>
|
||||
* resource path.
|
||||
*
|
||||
* @param resourceUrlPath the candidate resource URL path
|
||||
* @param locations the configured locations where to look up resources
|
||||
* @param chain the chain with remaining resolvers to delegate to
|
||||
* <p>This is useful when rendering URL links to clients.
|
||||
*
|
||||
* @return the resolved URL path or {@code null} if unresolved
|
||||
* @param resourcePath the internal resource path
|
||||
* @param locations the locations to search in when looking up resources
|
||||
* @param chain the chain of resolvers to delegate to
|
||||
* @return the resolved public URL path or {@code null} if unresolved
|
||||
*/
|
||||
String getPublicUrlPath(String resourceUrlPath, List<Resource> locations, ResourceResolverChain chain);
|
||||
String resolvePublicUrlPath(String resourcePath, List<? extends Resource> locations, ResourceResolverChain chain);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,40 +22,40 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* A contract for invoking a chain of {@link ResourceResolver}s where each resolver
|
||||
* is given a reference to the chain allowing it to delegate when necessary.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see ResourceResolver
|
||||
*/
|
||||
public interface ResourceResolverChain {
|
||||
|
||||
/**
|
||||
* Resolve the URL path of an incoming request to an actual {@link Resource}
|
||||
* to serve in the response.
|
||||
* Resolve the supplied request and request path to a {@link Resource} that
|
||||
* exists under one of the given resource locations.
|
||||
*
|
||||
* @param request the current request
|
||||
* @param requestPath the portion of the request path to use
|
||||
* @param locations the configured locations where to look up resources
|
||||
*
|
||||
* @return the resolved {@link Resource} or {@code null} if this resolver
|
||||
* could not resolve the resource
|
||||
* @param locations the locations to search in when looking up resources
|
||||
* @return the resolved resource or {@code null} if unresolved
|
||||
*/
|
||||
Resource resolveResource(HttpServletRequest request, String requestPath, List<Resource> locations);
|
||||
Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations);
|
||||
|
||||
/**
|
||||
* Resolve the given resource path to a URL path. This is useful when rendering
|
||||
* URL links to clients to determine the actual URL to use.
|
||||
* Resolve the externally facing <em>public</em> URL path for clients to use
|
||||
* to access the resource that is located at the given <em>internal</em>
|
||||
* resource path.
|
||||
*
|
||||
* @param resourcePath the resource path
|
||||
* @param locations the configured locations where to look up resources
|
||||
* <p>This is useful when rendering URL links to clients.
|
||||
*
|
||||
* @return the resolved URL path or {@code null} if this resolver could not
|
||||
* resolve the given resource path
|
||||
* @param resourcePath the internal resource path
|
||||
* @param locations the locations to search in when looking up resources
|
||||
* @return the resolved public URL path or {@code null} if unresolved
|
||||
*/
|
||||
String resolveUrlPath(String resourcePath, List<Resource> locations);
|
||||
String resolvePublicUrlPath(String resourcePath, List<? extends Resource> locations);
|
||||
|
||||
}
|
||||
|
|
|
@ -26,16 +26,18 @@ import javax.servlet.http.HttpServletResponseWrapper;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
/**
|
||||
* A filter that wraps the {@link HttpServletResponse} and overrides its
|
||||
* {@link HttpServletResponse#encodeURL(String) encodeURL} method in order to
|
||||
* translate resource request URLs.
|
||||
* translate internal resource request URLs into public URL paths for external
|
||||
* use.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class ResourceUrlEncodingFilter extends OncePerRequestFilter {
|
||||
|
@ -44,16 +46,18 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter {
|
|||
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
filterChain.doFilter(request, new ResourceUrlEncodingResponseWrapper(request, response));
|
||||
}
|
||||
|
||||
private class ResourceUrlEncodingResponseWrapper extends HttpServletResponseWrapper {
|
||||
|
||||
private static class ResourceUrlEncodingResponseWrapper extends HttpServletResponseWrapper {
|
||||
|
||||
private HttpServletRequest request;
|
||||
|
||||
|
||||
private ResourceUrlEncodingResponseWrapper(HttpServletRequest request, HttpServletResponse wrapped) {
|
||||
super(wrapped);
|
||||
this.request = request;
|
||||
|
@ -62,15 +66,15 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter {
|
|||
@Override
|
||||
public String encodeURL(String url) {
|
||||
String name = PublicResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR;
|
||||
PublicResourceUrlProvider translator = (PublicResourceUrlProvider) this.request.getAttribute(name);
|
||||
if (translator != null) {
|
||||
String translatedUrl = translator.getForRequestUrl(this.request, url);
|
||||
PublicResourceUrlProvider urlProvider = (PublicResourceUrlProvider) this.request.getAttribute(name);
|
||||
if (urlProvider != null) {
|
||||
String translatedUrl = urlProvider.getForRequestUrl(this.request, url);
|
||||
if (translatedUrl != null) {
|
||||
return super.encodeURL(translatedUrl);
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.debug("Request attribute exposing ResourceUrlPathProvider not found");
|
||||
logger.debug("Request attribute exposing PublicResourceUrlProvider not found under name: " + name);
|
||||
}
|
||||
return super.encodeURL(url);
|
||||
}
|
||||
|
|
|
@ -13,58 +13,61 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link PrefixResourceResolver}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class PrefixResourceResolverTests {
|
||||
|
||||
private ResourceResolverChain resolver;
|
||||
|
||||
private List<Resource> locations;
|
||||
private final List<? extends Resource> locations = Arrays.asList(new ClassPathResource("test/", getClass()));
|
||||
|
||||
private final String shaPrefix = "1df341f";
|
||||
|
||||
private ResourceResolverChain chain;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
List<ResourceResolver> resolvers = new ArrayList<ResourceResolver>();
|
||||
resolvers.add(new PrefixResourceResolver(this.shaPrefix));
|
||||
resolvers.add(new PathResourceResolver());
|
||||
this.resolver = new DefaultResourceResolverChain(resolvers);
|
||||
this.locations = new ArrayList<Resource>();
|
||||
this.locations.add(new ClassPathResource("test/", getClass()));
|
||||
this.chain = new DefaultResourceResolverChain(resolvers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveResource() {
|
||||
public void resolveResource() {
|
||||
String resourceId = "foo.css";
|
||||
Resource expected = new ClassPathResource("test/foo.css", getClass());
|
||||
Resource actual = this.resolver.resolveResource(null, "/" + this.shaPrefix + "/" + resourceId, this.locations);
|
||||
Resource actual = this.chain.resolveResource(null, "/" + this.shaPrefix + "/" + resourceId, this.locations);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveUrlPath() {
|
||||
public void resolvePublicUrlPath() {
|
||||
String resourceId = "/foo.css";
|
||||
String url = "/" + this.shaPrefix + resourceId;
|
||||
assertEquals(url, resolver.resolveUrlPath(resourceId, locations));
|
||||
assertEquals(url, chain.resolvePublicUrlPath(resourceId, locations));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testFailPrefixResolverConstructor() {
|
||||
PrefixResourceResolver resolver = new PrefixResourceResolver("");
|
||||
public void constructWithEmptyPrefix() {
|
||||
new PrefixResourceResolver(" ");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -44,25 +44,25 @@ import static org.junit.Assert.*;
|
|||
*/
|
||||
public class PublicResourceUrlProviderJavaConfigTests {
|
||||
|
||||
private MockFilterChain filterChain;
|
||||
private final TestServlet servlet = new TestServlet();
|
||||
|
||||
private TestServlet servlet;
|
||||
private MockFilterChain filterChain;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
|
||||
@Before
|
||||
@SuppressWarnings("resource")
|
||||
public void setup() throws Exception {
|
||||
|
||||
this.servlet = new TestServlet();
|
||||
this.filterChain = new MockFilterChain(this.servlet, new ResourceUrlEncodingFilter());
|
||||
|
||||
AnnotationConfigWebApplicationContext cxt = new AnnotationConfigWebApplicationContext();
|
||||
cxt.setServletContext(new MockServletContext());
|
||||
cxt.register(WebConfig.class);
|
||||
cxt.refresh();
|
||||
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
|
||||
ctx.setServletContext(new MockServletContext());
|
||||
ctx.register(WebConfig.class);
|
||||
ctx.refresh();
|
||||
|
||||
PublicResourceUrlProvider urlProvider = cxt.getBean(PublicResourceUrlProvider.class);
|
||||
PublicResourceUrlProvider urlProvider = ctx.getBean(PublicResourceUrlProvider.class);
|
||||
|
||||
this.request = new MockHttpServletRequest("GET", "/");
|
||||
request.setAttribute(PublicResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, urlProvider);
|
||||
|
|
Loading…
Reference in New Issue