Early removal of 5.x-deprecated code

Closes gh-27686
This commit is contained in:
Juergen Hoeller
2021-11-18 09:18:06 +01:00
parent 17cdd97c37
commit 4750a9430c
132 changed files with 89 additions and 9216 deletions

View File

@@ -85,32 +85,6 @@ public class HandlerMappingIntrospector
private Map<HandlerMapping, PathPatternMatchableHandlerMapping> pathPatternHandlerMappings = Collections.emptyMap();
/**
* Constructor for use with {@link ApplicationContextAware}.
*/
public HandlerMappingIntrospector() {
}
/**
* Constructor that detects the configured {@code HandlerMapping}s in the
* given {@code ApplicationContext} or falls back on
* "DispatcherServlet.properties" like the {@code DispatcherServlet}.
* @deprecated as of 4.3.12, in favor of {@link #setApplicationContext}
*/
@Deprecated
public HandlerMappingIntrospector(ApplicationContext context) {
this.handlerMappings = initHandlerMappings(context);
}
/**
* Return the configured or detected {@code HandlerMapping}s.
*/
public List<HandlerMapping> getHandlerMappings() {
return (this.handlerMappings != null ? this.handlerMappings : Collections.emptyList());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
@@ -125,6 +99,13 @@ public class HandlerMappingIntrospector
}
}
/**
* Return the configured or detected {@code HandlerMapping}s.
*/
public List<HandlerMapping> getHandlerMappings() {
return (this.handlerMappings != null ? this.handlerMappings : Collections.emptyList());
}
/**
* Find the {@link HandlerMapping} that would handle the given request and

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -108,34 +108,6 @@ public class LocaleChangeInterceptor implements HandlerInterceptor {
return this.ignoreInvalidLocale;
}
/**
* Specify whether to parse request parameter values as BCP 47 language tags
* instead of Java's legacy locale specification format.
* <p><b>NOTE: As of 5.1, this resolver leniently accepts the legacy
* {@link Locale#toString} format as well as BCP 47 language tags.</b>
* @since 4.3
* @see Locale#forLanguageTag(String)
* @see Locale#toLanguageTag()
* @deprecated as of 5.1 since it only accepts {@code true} now
*/
@Deprecated
public void setLanguageTagCompliant(boolean languageTagCompliant) {
if (!languageTagCompliant) {
throw new IllegalArgumentException("LocaleChangeInterceptor always accepts BCP 47 language tags");
}
}
/**
* Return whether to use BCP 47 language tags instead of Java's legacy
* locale specification format.
* @since 4.3
* @deprecated as of 5.1 since it always returns {@code true} now
*/
@Deprecated
public boolean isLanguageTagCompliant() {
return true;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

View File

@@ -1,259 +0,0 @@
/*
* Copyright 2002-2020 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Scanner;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.DigestUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
/**
* A {@link ResourceTransformer} implementation that helps handling resources
* within HTML5 AppCache manifests for HTML5 offline applications.
*
* <p>This transformer:
* <ul>
* <li>modifies links to match the public URL paths that should be exposed to clients,
* using configured {@code ResourceResolver} strategies
* <li>appends a comment in the manifest, containing a Hash (e.g. "# Hash: 9de0f09ed7caf84e885f1f0f11c7e326"),
* thus changing the content of the manifest in order to trigger an appcache reload in the browser.
* </ul>
*
* <p>All files that have the ".appcache" file extension, or the extension given in the constructor,
* will be transformed by this class. This hash is computed using the content of the appcache manifest
* and the content of the linked resources; so changing a resource linked in the manifest
* or the manifest itself should invalidate the browser cache.
*
* <p>In order to serve manifest files with the proper {@code "text/manifest"} content type,
* it is required to configure it with
* {@code contentNegotiationConfigurer.mediaType("appcache", MediaType.valueOf("text/manifest")}
* in a {@code WebMvcConfigurer}.
*
* @author Brian Clozel
* @since 4.1
* @see <a href="https://html.spec.whatwg.org/multipage/browsers.html#offline">HTML5 offline applications spec</a>
* @deprecated as of 5.3 since browser support is going away
*/
@Deprecated
public class AppCacheManifestTransformer extends ResourceTransformerSupport {
private static final String MANIFEST_HEADER = "CACHE MANIFEST";
private static final String CACHE_HEADER = "CACHE:";
private static final Collection<String> MANIFEST_SECTION_HEADERS =
Arrays.asList(MANIFEST_HEADER, "NETWORK:", "FALLBACK:", CACHE_HEADER);
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private static final Log logger = LogFactory.getLog(AppCacheManifestTransformer.class);
private final String fileExtension;
/**
* Create an AppCacheResourceTransformer that transforms files with extension ".appcache".
*/
public AppCacheManifestTransformer() {
this("appcache");
}
/**
* Create an AppCacheResourceTransformer that transforms files with the extension
* given as a parameter.
*/
public AppCacheManifestTransformer(String fileExtension) {
this.fileExtension = fileExtension;
}
@Override
public Resource transform(HttpServletRequest request, Resource resource,
ResourceTransformerChain chain) throws IOException {
resource = chain.transform(request, resource);
if (!this.fileExtension.equals(StringUtils.getFilenameExtension(resource.getFilename()))) {
return resource;
}
byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
String content = new String(bytes, DEFAULT_CHARSET);
if (!content.startsWith(MANIFEST_HEADER)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping " + resource + ": Manifest does not start with 'CACHE MANIFEST'");
}
return resource;
}
@SuppressWarnings("resource")
Scanner scanner = new Scanner(content);
LineInfo previous = null;
LineAggregator aggregator = new LineAggregator(resource, content);
while (scanner.hasNext()) {
String line = scanner.nextLine();
LineInfo current = new LineInfo(line, previous);
LineOutput lineOutput = processLine(current, request, resource, chain);
aggregator.add(lineOutput);
previous = current;
}
return aggregator.createResource();
}
private static byte[] getResourceBytes(Resource resource) throws IOException {
return FileCopyUtils.copyToByteArray(resource.getInputStream());
}
private LineOutput processLine(LineInfo info, HttpServletRequest request,
Resource resource, ResourceTransformerChain transformerChain) {
if (!info.isLink()) {
return new LineOutput(info.getLine(), null);
}
Resource appCacheResource = transformerChain.getResolverChain()
.resolveResource(null, info.getLine(), Collections.singletonList(resource));
String path = info.getLine();
String absolutePath = toAbsolutePath(path, request);
String newPath = resolveUrlPath(absolutePath, request, resource, transformerChain);
return new LineOutput((newPath != null ? newPath : path), appCacheResource);
}
private static class LineInfo {
private final String line;
private final boolean cacheSection;
private final boolean link;
public LineInfo(String line, @Nullable LineInfo previous) {
this.line = line;
this.cacheSection = initCacheSectionFlag(line, previous);
this.link = iniLinkFlag(line, this.cacheSection);
}
private static boolean initCacheSectionFlag(String line, @Nullable LineInfo previousLine) {
String trimmedLine = line.trim();
if (MANIFEST_SECTION_HEADERS.contains(trimmedLine)) {
return trimmedLine.equals(CACHE_HEADER);
}
else if (previousLine != null) {
return previousLine.isCacheSection();
}
throw new IllegalStateException(
"Manifest does not start with " + MANIFEST_HEADER + ": " + line);
}
private static boolean iniLinkFlag(String line, boolean isCacheSection) {
return (isCacheSection && StringUtils.hasText(line) && !line.startsWith("#")
&& !line.startsWith("//") && !hasScheme(line));
}
private static boolean hasScheme(String line) {
int index = line.indexOf(':');
return (line.startsWith("//") || (index > 0 && !line.substring(0, index).contains("/")));
}
public String getLine() {
return this.line;
}
public boolean isCacheSection() {
return this.cacheSection;
}
public boolean isLink() {
return this.link;
}
}
private static class LineOutput {
private final String line;
@Nullable
private final Resource resource;
public LineOutput(String line, @Nullable Resource resource) {
this.line = line;
this.resource = resource;
}
public String getLine() {
return this.line;
}
@Nullable
public Resource getResource() {
return this.resource;
}
}
private static class LineAggregator {
private final StringWriter writer = new StringWriter();
private final ByteArrayOutputStream baos;
private final Resource resource;
public LineAggregator(Resource resource, String content) {
this.resource = resource;
this.baos = new ByteArrayOutputStream(content.length());
}
public void add(LineOutput lineOutput) throws IOException {
this.writer.write(lineOutput.getLine() + "\n");
byte[] bytes = (lineOutput.getResource() != null ?
DigestUtils.md5Digest(getResourceBytes(lineOutput.getResource())) :
lineOutput.getLine().getBytes(DEFAULT_CHARSET));
this.baos.write(bytes);
}
public TransformedResource createResource() {
String hash = DigestUtils.md5DigestAsHex(this.baos.toByteArray());
this.writer.write("\n" + "# Hash: " + hash);
byte[] bytes = this.writer.toString().getBytes(DEFAULT_CHARSET);
return new TransformedResource(this.resource, bytes);
}
}
}

View File

@@ -72,8 +72,7 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport {
String filename = resource.getFilename();
if (!"css".equals(StringUtils.getFilenameExtension(filename)) ||
resource instanceof EncodedResourceResolver.EncodedResource ||
resource instanceof GzipResourceResolver.GzippedResource) {
resource instanceof EncodedResourceResolver.EncodedResource) {
return resource;
}

View File

@@ -1,174 +0,0 @@
/*
* Copyright 2002-2018 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
/**
* A {@code ResourceResolver} that delegates to the chain to locate a resource
* and then attempts to find a variation with the ".gz" extension.
*
* <p>The resolver gets involved only if the "Accept-Encoding" request header
* contains the value "gzip" indicating the client accepts gzipped responses.
*
* @author Jeremy Grelle
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 4.1
* @deprecated as of 5.1, in favor of using {@link EncodedResourceResolver}
*/
@Deprecated
public class GzipResourceResolver extends AbstractResourceResolver {
@Override
protected Resource resolveResourceInternal(@Nullable HttpServletRequest request, String requestPath,
List<? extends Resource> locations, ResourceResolverChain chain) {
Resource resource = chain.resolveResource(request, requestPath, locations);
if (resource == null || (request != null && !isGzipAccepted(request))) {
return resource;
}
try {
Resource gzipped = new GzippedResource(resource);
if (gzipped.exists()) {
return gzipped;
}
}
catch (IOException ex) {
logger.trace("No gzip resource for [" + resource.getFilename() + "]", ex);
}
return resource;
}
private boolean isGzipAccepted(HttpServletRequest request) {
String value = request.getHeader("Accept-Encoding");
return (value != null && value.toLowerCase().contains("gzip"));
}
@Override
protected String resolveUrlPathInternal(String resourceUrlPath,
List<? extends Resource> locations, ResourceResolverChain chain) {
return chain.resolveUrlPath(resourceUrlPath, locations);
}
/**
* A gzipped {@link HttpResource}.
*/
static final class GzippedResource extends AbstractResource implements HttpResource {
private final Resource original;
private final Resource gzipped;
public GzippedResource(Resource original) throws IOException {
this.original = original;
this.gzipped = original.createRelative(original.getFilename() + ".gz");
}
@Override
public InputStream getInputStream() throws IOException {
return this.gzipped.getInputStream();
}
@Override
public boolean exists() {
return this.gzipped.exists();
}
@Override
public boolean isReadable() {
return this.gzipped.isReadable();
}
@Override
public boolean isOpen() {
return this.gzipped.isOpen();
}
@Override
public boolean isFile() {
return this.gzipped.isFile();
}
@Override
public URL getURL() throws IOException {
return this.gzipped.getURL();
}
@Override
public URI getURI() throws IOException {
return this.gzipped.getURI();
}
@Override
public File getFile() throws IOException {
return this.gzipped.getFile();
}
@Override
public long contentLength() throws IOException {
return this.gzipped.contentLength();
}
@Override
public long lastModified() throws IOException {
return this.gzipped.lastModified();
}
@Override
public Resource createRelative(String relativePath) throws IOException {
return this.gzipped.createRelative(relativePath);
}
@Override
@Nullable
public String getFilename() {
return this.original.getFilename();
}
@Override
public String getDescription() {
return this.gzipped.getDescription();
}
@Override
public HttpHeaders getResponseHeaders() {
HttpHeaders headers = (this.original instanceof HttpResource ?
((HttpResource) this.original).getResponseHeaders() : new HttpHeaders());
headers.add(HttpHeaders.CONTENT_ENCODING, "gzip");
headers.add(HttpHeaders.VARY, HttpHeaders.ACCEPT_ENCODING);
return headers;
}
}
}

View File

@@ -475,22 +475,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
}
/**
* Check and prepare the given request and response according to the settings
* of this generator.
* @see #checkRequest(HttpServletRequest)
* @see #prepareResponse(HttpServletResponse)
* @deprecated as of 4.2, since the {@code lastModified} flag is effectively ignored,
* with a must-revalidate header only generated if explicitly configured
*/
@Deprecated
protected final void checkAndPrepare(
HttpServletRequest request, HttpServletResponse response, boolean lastModified) throws ServletException {
checkRequest(request);
prepareResponse(response);
}
/**
* Check and prepare the given request and response according to the settings
* of this generator.

View File

@@ -23,7 +23,6 @@ import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.RequestToViewNameTranslator;
import org.springframework.web.util.ServletRequestPathUtils;
import org.springframework.web.util.UrlPathHelper;
/**
* {@link RequestToViewNameTranslator} that simply transforms the URI of
@@ -122,48 +121,6 @@ public class DefaultRequestToViewNameTranslator implements RequestToViewNameTran
this.stripExtension = stripExtension;
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
* @deprecated as of 5.3, the path is resolved externally and obtained with
* {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)}
*/
@Deprecated
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
* @deprecated as of 5.3, the path is resolved externally and obtained with
* {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)}
*/
@Deprecated
public void setUrlDecode(boolean urlDecode) {
}
/**
* Set if ";" (semicolon) content should be stripped from the request URI.
* @see org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean)
* @deprecated as of 5.3, the path is resolved externally and obtained with
* {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)}
*/
@Deprecated
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
}
/**
* Set the {@link org.springframework.web.util.UrlPathHelper} to use for
* the resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclass,
* or to share common UrlPathHelper settings across multiple web components.
* @deprecated as of 5.3, the path is resolved externally and obtained with
* {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)}
*/
@Deprecated
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
}
/**
* Translates the request URI of the incoming {@link HttpServletRequest}

View File

@@ -467,10 +467,9 @@ public class MvcNamespaceTests {
assertThat(locationCharsets.values().iterator().next()).isEqualTo(StandardCharsets.ISO_8859_1);
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers).hasSize(3);
assertThat(transformers).hasSize(2);
assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class);
assertThat(transformers.get(1)).isInstanceOf(CssLinkResourceTransformer.class);
assertThat(transformers.get(2)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class);
CachingResourceTransformer cachingTransformer = (CachingResourceTransformer) transformers.get(0);
assertThat(cachingTransformer.getCache()).isInstanceOf(ConcurrentMapCache.class);
@@ -506,9 +505,8 @@ public class MvcNamespaceTests {
.isInstanceOf(ContentVersionStrategy.class);
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers).hasSize(2);
assertThat(transformers).hasSize(1);
assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class);
assertThat(transformers.get(1)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class);
}
@Test

View File

@@ -167,14 +167,12 @@ public class ResourceHandlerRegistryTests {
}
@Test
@SuppressWarnings("deprecation")
public void resourceChainWithVersionResolver() {
VersionResourceResolver versionResolver = new VersionResourceResolver()
.addFixedVersionStrategy("fixed", "/**/*.js")
.addContentVersionStrategy("/**");
this.registration.resourceChain(true).addResolver(versionResolver)
.addTransformer(new org.springframework.web.servlet.resource.AppCacheManifestTransformer());
this.registration.resourceChain(true).addResolver(versionResolver);
ResourceHttpRequestHandler handler = getHandler("/resources/**");
List<ResourceResolver> resolvers = handler.getResourceResolvers();
@@ -185,22 +183,18 @@ public class ResourceHandlerRegistryTests {
assertThat(resolvers.get(3)).isInstanceOf(PathResourceResolver.class);
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers).hasSize(3);
assertThat(transformers).hasSize(2);
assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class);
assertThat(transformers.get(1)).isInstanceOf(CssLinkResourceTransformer.class);
assertThat(transformers.get(2)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class);
}
@Test
@SuppressWarnings("deprecation")
public void resourceChainWithOverrides() {
CachingResourceResolver cachingResolver = Mockito.mock(CachingResourceResolver.class);
VersionResourceResolver versionResolver = Mockito.mock(VersionResourceResolver.class);
WebJarsResourceResolver webjarsResolver = Mockito.mock(WebJarsResourceResolver.class);
PathResourceResolver pathResourceResolver = new PathResourceResolver();
CachingResourceTransformer cachingTransformer = Mockito.mock(CachingResourceTransformer.class);
org.springframework.web.servlet.resource.AppCacheManifestTransformer appCacheTransformer =
Mockito.mock(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class);
CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer();
this.registration.setCachePeriod(3600)
@@ -210,7 +204,6 @@ public class ResourceHandlerRegistryTests {
.addResolver(webjarsResolver)
.addResolver(pathResourceResolver)
.addTransformer(cachingTransformer)
.addTransformer(appCacheTransformer)
.addTransformer(cssLinkTransformer);
ResourceHttpRequestHandler handler = getHandler("/resources/**");
@@ -222,10 +215,9 @@ public class ResourceHandlerRegistryTests {
assertThat(resolvers.get(3)).isSameAs(pathResourceResolver);
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers).hasSize(3);
assertThat(transformers).hasSize(2);
assertThat(transformers.get(0)).isSameAs(cachingTransformer);
assertThat(transformers.get(1)).isSameAs(appCacheTransformer);
assertThat(transformers.get(2)).isSameAs(cssLinkTransformer);
assertThat(transformers.get(1)).isSameAs(cssLinkTransformer);
}
@Test

View File

@@ -1,122 +0,0 @@
/*
* Copyright 2002-2021 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* 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.Collections;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for {@link AppCacheManifestTransformer}.
*
* @author Brian Clozel
* @author Rossen Stoyanchev
*/
@SuppressWarnings("deprecation")
public class AppCacheManifestTransformerTests {
private final AppCacheManifestTransformer transformer = new AppCacheManifestTransformer();
private ResourceTransformerChain chain;
private HttpServletRequest request;
@BeforeEach
public void setup() {
VersionResourceResolver versionResolver = new VersionResourceResolver();
versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy()));
PathResourceResolver pathResolver = new PathResourceResolver();
pathResolver.setAllowedLocations(new ClassPathResource("test/", getClass()));
List<ResourceResolver> resolvers = new ArrayList<>();
resolvers.add(versionResolver);
resolvers.add(pathResolver);
ResourceResolverChain resolverChain = new DefaultResourceResolverChain(resolvers);
this.chain = new DefaultResourceTransformerChain(resolverChain, Collections.emptyList());
this.transformer.setResourceUrlProvider(createUrlProvider(resolvers));
}
private ResourceUrlProvider createUrlProvider(List<ResourceResolver> resolvers) {
ClassPathResource allowedLocation = new ClassPathResource("test/", getClass());
ResourceHttpRequestHandler resourceHandler = new ResourceHttpRequestHandler();
resourceHandler.setResourceResolvers(resolvers);
resourceHandler.setLocations(Collections.singletonList(allowedLocation));
ResourceUrlProvider resourceUrlProvider = new ResourceUrlProvider();
resourceUrlProvider.setHandlerMap(Collections.singletonMap("/static/**", resourceHandler));
return resourceUrlProvider;
}
@Test
public void noTransformIfExtensionDoesNotMatch() throws Exception {
this.request = new MockHttpServletRequest("GET", "/static/foo.css");
Resource resource = getResource("foo.css");
Resource result = this.transformer.transform(this.request, resource, this.chain);
assertThat(result).isEqualTo(resource);
}
@Test
public void syntaxErrorInManifest() throws Exception {
this.request = new MockHttpServletRequest("GET", "/static/error.appcache");
Resource resource = getResource("error.appcache");
Resource result = this.transformer.transform(this.request, resource, this.chain);
assertThat(result).isEqualTo(resource);
}
@Test
public void transformManifest() throws Exception {
this.request = new MockHttpServletRequest("GET", "/static/test.appcache");
Resource resource = getResource("test.appcache");
Resource actual = this.transformer.transform(this.request, resource, this.chain);
byte[] bytes = FileCopyUtils.copyToByteArray(actual.getInputStream());
String content = new String(bytes, "UTF-8");
assertThat(content).as("rewrite resource links")
.contains("/static/foo-e36d2e05253c6c7085a91522ce43a0b4.css")
.contains("/static/bar-11e16cf79faee7ac698c805cf28248d2.css")
.contains("/static/js/bar-bd508c62235b832d960298ca6c0b7645.js");
assertThat(content).as("not rewrite external resources")
.contains("//example.org/style.css")
.contains("https://example.org/image.png");
assertThat(content).as("generate fingerprint")
.contains("# Hash: 65ebc023e50b2b731fcace2871f0dae3");
}
private Resource getResource(String filePath) {
return new ClassPathResource("test/" + filePath, getClass());
}
}

View File

@@ -22,7 +22,6 @@
<bean class="org.springframework.web.servlet.resource.CachingResourceTransformer">
<constructor-arg name="cache" ref="resourceCache" />
</bean>
<bean class="org.springframework.web.servlet.resource.AppCacheManifestTransformer"/>
</mvc:transformers>
</mvc:resource-chain>
</mvc:resources>

View File

@@ -35,9 +35,6 @@
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
<mvc:transformers>
<bean class="org.springframework.web.servlet.resource.AppCacheManifestTransformer"/>
</mvc:transformers>
</mvc:resource-chain>
</mvc:resources>