21 changed files with 21 additions and 783 deletions
@ -1,129 +0,0 @@
@@ -1,129 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2024 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.accept; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Map; |
||||
|
||||
import jakarta.servlet.http.HttpServletRequest; |
||||
|
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.MediaTypeFactory; |
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.web.context.request.NativeWebRequest; |
||||
import org.springframework.web.util.UriUtils; |
||||
import org.springframework.web.util.UrlPathHelper; |
||||
|
||||
/** |
||||
* A {@code ContentNegotiationStrategy} that resolves the file extension in the |
||||
* request path to a key to be used to look up a media type. |
||||
* |
||||
* <p>If the file extension is not found in the explicit registrations provided |
||||
* to the constructor, the {@link MediaTypeFactory} is used as a fallback |
||||
* mechanism. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.2 |
||||
* @deprecated as of 5.2.4. See class-level note in |
||||
* {@link ContentNegotiationManagerFactoryBean} on the deprecation of path |
||||
* extension config options. |
||||
*/ |
||||
@Deprecated |
||||
public class PathExtensionContentNegotiationStrategy extends AbstractMappingContentNegotiationStrategy { |
||||
|
||||
private UrlPathHelper urlPathHelper = new UrlPathHelper(); |
||||
|
||||
|
||||
/** |
||||
* Create an instance without any mappings to start with. Mappings may be added |
||||
* later on if any extensions are resolved through the Java Activation framework. |
||||
*/ |
||||
public PathExtensionContentNegotiationStrategy() { |
||||
this(null); |
||||
} |
||||
|
||||
/** |
||||
* Create an instance with the given map of file extensions and media types. |
||||
*/ |
||||
public PathExtensionContentNegotiationStrategy(@Nullable Map<String, MediaType> mediaTypes) { |
||||
super(mediaTypes); |
||||
setUseRegisteredExtensionsOnly(false); |
||||
setIgnoreUnknownExtensions(true); |
||||
this.urlPathHelper.setUrlDecode(false); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Configure a {@code UrlPathHelper} to use in {@link #getMediaTypeKey} |
||||
* in order to derive the lookup path for a target request URL path. |
||||
* @since 4.2.8 |
||||
*/ |
||||
public void setUrlPathHelper(UrlPathHelper urlPathHelper) { |
||||
this.urlPathHelper = urlPathHelper; |
||||
} |
||||
|
||||
/** |
||||
* Indicate whether to use the Java Activation Framework as a fallback option |
||||
* to map from file extensions to media types. |
||||
* @deprecated as of 5.0, in favor of {@link #setUseRegisteredExtensionsOnly(boolean)}. |
||||
*/ |
||||
@Deprecated |
||||
public void setUseJaf(boolean useJaf) { |
||||
setUseRegisteredExtensionsOnly(!useJaf); |
||||
} |
||||
|
||||
@Override |
||||
@Nullable |
||||
protected String getMediaTypeKey(NativeWebRequest webRequest) { |
||||
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); |
||||
if (request == null) { |
||||
return null; |
||||
} |
||||
// Ignore LOOKUP_PATH attribute, use our own "fixed" UrlPathHelper with decoding off
|
||||
String path = this.urlPathHelper.getLookupPathForRequest(request); |
||||
String extension = UriUtils.extractFileExtension(path); |
||||
return (StringUtils.hasText(extension) ? extension.toLowerCase(Locale.ROOT) : null); |
||||
} |
||||
|
||||
/** |
||||
* A public method exposing the knowledge of the path extension strategy to |
||||
* resolve file extensions to a {@link MediaType} in this case for a given |
||||
* {@link Resource}. The method first looks up any explicitly registered |
||||
* file extensions first and then falls back on {@link MediaTypeFactory} if available. |
||||
* @param resource the resource to look up |
||||
* @return the MediaType for the extension, or {@code null} if none found |
||||
* @since 4.3 |
||||
*/ |
||||
@Nullable |
||||
public MediaType getMediaTypeForResource(Resource resource) { |
||||
Assert.notNull(resource, "Resource must not be null"); |
||||
MediaType mediaType = null; |
||||
String filename = resource.getFilename(); |
||||
String extension = StringUtils.getFilenameExtension(filename); |
||||
if (extension != null) { |
||||
mediaType = lookupMediaType(extension); |
||||
} |
||||
if (mediaType == null) { |
||||
mediaType = MediaTypeFactory.getMediaType(filename).orElse(null); |
||||
} |
||||
return mediaType; |
||||
} |
||||
|
||||
} |
||||
@ -1,118 +0,0 @@
@@ -1,118 +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.accept; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import jakarta.servlet.ServletContext; |
||||
|
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException; |
||||
import org.springframework.web.context.request.NativeWebRequest; |
||||
|
||||
/** |
||||
* Extends {@code PathExtensionContentNegotiationStrategy} that also uses |
||||
* {@link ServletContext#getMimeType(String)} to resolve file extensions. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.2 |
||||
* @deprecated as of 5.2.4. See class-level note in |
||||
* {@link ContentNegotiationManagerFactoryBean} on the deprecation of path |
||||
* extension config options. |
||||
*/ |
||||
@Deprecated |
||||
public class ServletPathExtensionContentNegotiationStrategy extends PathExtensionContentNegotiationStrategy { |
||||
|
||||
private final ServletContext servletContext; |
||||
|
||||
|
||||
/** |
||||
* Create an instance without any mappings to start with. Mappings may be |
||||
* added later when extensions are resolved through |
||||
* {@link ServletContext#getMimeType(String)} or via |
||||
* {@link org.springframework.http.MediaTypeFactory}. |
||||
*/ |
||||
public ServletPathExtensionContentNegotiationStrategy(ServletContext context) { |
||||
this(context, null); |
||||
} |
||||
|
||||
/** |
||||
* Create an instance with the given extension-to-MediaType lookup. |
||||
*/ |
||||
public ServletPathExtensionContentNegotiationStrategy( |
||||
ServletContext servletContext, @Nullable Map<String, MediaType> mediaTypes) { |
||||
|
||||
super(mediaTypes); |
||||
Assert.notNull(servletContext, "ServletContext is required"); |
||||
this.servletContext = servletContext; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Resolve file extension via {@link ServletContext#getMimeType(String)} |
||||
* and also delegate to base class for a potential |
||||
* {@link org.springframework.http.MediaTypeFactory} lookup. |
||||
*/ |
||||
@Override |
||||
@Nullable |
||||
protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension) |
||||
throws HttpMediaTypeNotAcceptableException { |
||||
|
||||
MediaType mediaType = null; |
||||
String mimeType = this.servletContext.getMimeType("file." + extension); |
||||
if (StringUtils.hasText(mimeType)) { |
||||
mediaType = MediaType.parseMediaType(mimeType); |
||||
} |
||||
if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { |
||||
MediaType superMediaType = super.handleNoMatch(webRequest, extension); |
||||
if (superMediaType != null) { |
||||
mediaType = superMediaType; |
||||
} |
||||
} |
||||
return mediaType; |
||||
} |
||||
|
||||
/** |
||||
* Extends the base class
|
||||
* {@link PathExtensionContentNegotiationStrategy#getMediaTypeForResource} |
||||
* with the ability to also look up through the ServletContext. |
||||
* @param resource the resource to look up |
||||
* @return the MediaType for the extension, or {@code null} if none found |
||||
* @since 4.3 |
||||
*/ |
||||
@Override |
||||
@Nullable |
||||
public MediaType getMediaTypeForResource(Resource resource) { |
||||
MediaType mediaType = null; |
||||
String mimeType = this.servletContext.getMimeType(resource.getFilename()); |
||||
if (StringUtils.hasText(mimeType)) { |
||||
mediaType = MediaType.parseMediaType(mimeType); |
||||
} |
||||
if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { |
||||
MediaType superMediaType = super.getMediaTypeForResource(resource); |
||||
if (superMediaType != null) { |
||||
mediaType = superMediaType; |
||||
} |
||||
} |
||||
return mediaType; |
||||
} |
||||
|
||||
} |
||||
@ -1,110 +0,0 @@
@@ -1,110 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2024 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.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException; |
||||
import org.springframework.web.context.request.NativeWebRequest; |
||||
import org.springframework.web.context.request.ServletWebRequest; |
||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
||||
|
||||
/** |
||||
* A test fixture for {@link PathExtensionContentNegotiationStrategy}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.2 |
||||
*/ |
||||
@SuppressWarnings("deprecation") |
||||
class PathExtensionContentNegotiationStrategyTests { |
||||
|
||||
private final MockHttpServletRequest servletRequest = new MockHttpServletRequest(); |
||||
|
||||
private final NativeWebRequest webRequest = new ServletWebRequest(servletRequest); |
||||
|
||||
private PathExtensionContentNegotiationStrategy strategy = new PathExtensionContentNegotiationStrategy(); |
||||
|
||||
|
||||
@Test |
||||
void resolveMediaTypesFromMapping() throws Exception { |
||||
this.servletRequest.setRequestURI("test.html"); |
||||
|
||||
List<MediaType> mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); |
||||
|
||||
assertThat(mediaTypes).containsExactly(new MediaType("text", "html")); |
||||
|
||||
Map<String, MediaType> mapping = Collections.singletonMap("HTML", MediaType.APPLICATION_XHTML_XML); |
||||
this.strategy = new PathExtensionContentNegotiationStrategy(mapping); |
||||
mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); |
||||
|
||||
assertThat(mediaTypes).containsExactly(new MediaType("application", "xhtml+xml")); |
||||
} |
||||
|
||||
@Test |
||||
void resolveMediaTypesFromMediaTypeFactory() throws Exception { |
||||
this.servletRequest.setRequestURI("test.xls"); |
||||
|
||||
List<MediaType> mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); |
||||
|
||||
assertThat(mediaTypes).containsExactly(new MediaType("application", "vnd.ms-excel")); |
||||
} |
||||
|
||||
@Test // SPR-8678
|
||||
void getMediaTypeFilenameWithContextPath() throws Exception { |
||||
this.servletRequest.setContextPath("/project-1.0.0.M3"); |
||||
this.servletRequest.setRequestURI("/project-1.0.0.M3/"); |
||||
assertThat(this.strategy.resolveMediaTypes(webRequest)).as("Context path should be excluded").isEqualTo(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST); |
||||
|
||||
this.servletRequest.setRequestURI("/project-1.0.0.M3"); |
||||
assertThat(this.strategy.resolveMediaTypes(webRequest)).as("Context path should be excluded").isEqualTo(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST); |
||||
} |
||||
|
||||
@Test // SPR-9390
|
||||
void getMediaTypeFilenameWithEncodedURI() throws Exception { |
||||
this.servletRequest.setRequestURI("/quo%20vadis%3f.html"); |
||||
List<MediaType> result = this.strategy.resolveMediaTypes(webRequest); |
||||
|
||||
assertThat(result).as("Invalid content type").isEqualTo(Collections.singletonList(new MediaType("text", "html"))); |
||||
} |
||||
|
||||
@Test // SPR-10170
|
||||
void resolveMediaTypesIgnoreUnknownExtension() throws Exception { |
||||
this.servletRequest.setRequestURI("test.foobar"); |
||||
|
||||
List<MediaType> mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); |
||||
|
||||
assertThat(mediaTypes).isEqualTo(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST); |
||||
} |
||||
|
||||
@Test |
||||
void resolveMediaTypesDoNotIgnoreUnknownExtension() { |
||||
this.servletRequest.setRequestURI("test.foobar"); |
||||
|
||||
this.strategy.setIgnoreUnknownExtensions(false); |
||||
assertThatExceptionOfType(HttpMediaTypeNotAcceptableException.class) |
||||
.isThrownBy(() -> this.strategy.resolveMediaTypes(this.webRequest)); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue