Fix ClassCastException when setting media types
Issue: SPR-10019
This commit is contained in:
parent
42cdb200ed
commit
9f9f1ed253
|
|
@ -20,6 +20,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
@ -52,7 +53,7 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
|
|
||||||
private boolean ignoreAcceptHeader = false;
|
private boolean ignoreAcceptHeader = false;
|
||||||
|
|
||||||
private Properties mediaTypes = new Properties();
|
private Map<String, MediaType> mediaTypes = new HashMap<String, MediaType>();
|
||||||
|
|
||||||
private Boolean useJaf;
|
private Boolean useJaf;
|
||||||
|
|
||||||
|
|
@ -64,7 +65,6 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
|
|
||||||
private ServletContext servletContext;
|
private ServletContext servletContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicate whether the extension of the request path should be used to determine
|
* Indicate whether the extension of the request path should be used to determine
|
||||||
* the requested media type with the <em>highest priority</em>.
|
* the requested media type with the <em>highest priority</em>.
|
||||||
|
|
@ -77,21 +77,43 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add mappings from file extensions to media types.
|
* Add mappings from file extensions to media types represented as strings.
|
||||||
* <p>If this property is not set, the Java Action Framework, if available, may
|
* <p>When this mapping is not set or when an extension is not found, the Java
|
||||||
* still be used in conjunction with {@link #setFavorPathExtension(boolean)}.
|
* Action Framework, if available, may be used if enabled via
|
||||||
|
* {@link #setFavorPathExtension(boolean)}.
|
||||||
|
*
|
||||||
|
* @see #addMediaType(String, MediaType)
|
||||||
|
* @see #addMediaTypes(Map)
|
||||||
*/
|
*/
|
||||||
public void setMediaTypes(Properties mediaTypes) {
|
public void setMediaTypes(Properties mediaTypes) {
|
||||||
if (!CollectionUtils.isEmpty(mediaTypes)) {
|
if (!CollectionUtils.isEmpty(mediaTypes)) {
|
||||||
for (Map.Entry<Object, Object> entry : mediaTypes.entrySet()) {
|
for (Entry<Object, Object> entry : mediaTypes.entrySet()) {
|
||||||
String extension = ((String) entry.getKey()).toLowerCase(Locale.ENGLISH);
|
String extension = ((String)entry.getKey()).toLowerCase(Locale.ENGLISH);
|
||||||
this.mediaTypes.put(extension, MediaType.valueOf((String) entry.getValue()));
|
this.mediaTypes.put(extension, MediaType.valueOf((String) entry.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Properties getMediaTypes() {
|
/**
|
||||||
return this.mediaTypes;
|
* Add a mapping from a file extension to a media type.
|
||||||
|
* <p>If no mapping is added or when an extension is not found, the Java
|
||||||
|
* Action Framework, if available, may be used if enabled via
|
||||||
|
* {@link #setFavorPathExtension(boolean)}.
|
||||||
|
*/
|
||||||
|
public void addMediaType(String fileExtension, MediaType mediaType) {
|
||||||
|
this.mediaTypes.put(fileExtension, mediaType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add mappings from file extensions to media types.
|
||||||
|
* <p>If no mappings are added or when an extension is not found, the Java
|
||||||
|
* Action Framework, if available, may be used if enabled via
|
||||||
|
* {@link #setFavorPathExtension(boolean)}.
|
||||||
|
*/
|
||||||
|
public void addMediaTypes(Map<String, MediaType> mediaTypes) {
|
||||||
|
if (mediaTypes != null) {
|
||||||
|
this.mediaTypes.putAll(mediaTypes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,6 +121,7 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
* to map from file extensions to media types. This is used only when
|
* to map from file extensions to media types. This is used only when
|
||||||
* {@link #setFavorPathExtension(boolean)} is set to {@code true}.
|
* {@link #setFavorPathExtension(boolean)} is set to {@code true}.
|
||||||
* <p>The default value is {@code true}.
|
* <p>The default value is {@code true}.
|
||||||
|
*
|
||||||
* @see #parameterName
|
* @see #parameterName
|
||||||
* @see #setMediaTypes(Properties)
|
* @see #setMediaTypes(Properties)
|
||||||
*/
|
*/
|
||||||
|
|
@ -115,6 +138,7 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
* {@code "application/pdf"} regardless of the {@code Accept} header.
|
* {@code "application/pdf"} regardless of the {@code Accept} header.
|
||||||
* <p>To use this option effectively you must also configure the MediaType
|
* <p>To use this option effectively you must also configure the MediaType
|
||||||
* type mappings via {@link #setMediaTypes(Properties)}.
|
* type mappings via {@link #setMediaTypes(Properties)}.
|
||||||
|
*
|
||||||
* @see #setParameterName(String)
|
* @see #setParameterName(String)
|
||||||
*/
|
*/
|
||||||
public void setFavorParameter(boolean favorParameter) {
|
public void setFavorParameter(boolean favorParameter) {
|
||||||
|
|
@ -145,8 +169,8 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
/**
|
/**
|
||||||
* Set the default content type.
|
* Set the default content type.
|
||||||
* <p>This content type will be used when neither the request path extension,
|
* <p>This content type will be used when neither the request path extension,
|
||||||
* nor a request parameter, nor the {@code Accept} header could help determine
|
* nor a request parameter, nor the {@code Accept} header could help
|
||||||
* the requested content type.
|
* determine the requested content type.
|
||||||
*/
|
*/
|
||||||
public void setDefaultContentType(MediaType defaultContentType) {
|
public void setDefaultContentType(MediaType defaultContentType) {
|
||||||
this.defaultContentType = defaultContentType;
|
this.defaultContentType = defaultContentType;
|
||||||
|
|
@ -159,16 +183,12 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
List<ContentNegotiationStrategy> strategies = new ArrayList<ContentNegotiationStrategy>();
|
List<ContentNegotiationStrategy> strategies = new ArrayList<ContentNegotiationStrategy>();
|
||||||
|
|
||||||
Map<String, MediaType> mediaTypesMap = new HashMap<String, MediaType>();
|
|
||||||
CollectionUtils.mergePropertiesIntoMap(this.mediaTypes, mediaTypesMap);
|
|
||||||
|
|
||||||
if (this.favorPathExtension) {
|
if (this.favorPathExtension) {
|
||||||
PathExtensionContentNegotiationStrategy strategy;
|
PathExtensionContentNegotiationStrategy strategy;
|
||||||
if (this.servletContext != null) {
|
if (this.servletContext != null) {
|
||||||
strategy = new ServletPathExtensionContentNegotiationStrategy(this.servletContext, mediaTypesMap);
|
strategy = new ServletPathExtensionContentNegotiationStrategy(this.servletContext, this.mediaTypes);
|
||||||
}
|
} else {
|
||||||
else {
|
strategy = new PathExtensionContentNegotiationStrategy(this.mediaTypes);
|
||||||
strategy = new PathExtensionContentNegotiationStrategy(mediaTypesMap);
|
|
||||||
}
|
}
|
||||||
if (this.useJaf != null) {
|
if (this.useJaf != null) {
|
||||||
strategy.setUseJaf(this.useJaf);
|
strategy.setUseJaf(this.useJaf);
|
||||||
|
|
@ -177,7 +197,7 @@ public class ContentNegotiationManagerFactoryBean
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.favorParameter) {
|
if (this.favorParameter) {
|
||||||
ParameterContentNegotiationStrategy strategy = new ParameterContentNegotiationStrategy(mediaTypesMap);
|
ParameterContentNegotiationStrategy strategy = new ParameterContentNegotiationStrategy(this.mediaTypes);
|
||||||
strategy.setParameterName(this.parameterName);
|
strategy.setParameterName(this.parameterName);
|
||||||
strategies.add(strategy);
|
strategies.add(strategy);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Properties;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -74,9 +75,9 @@ public class ContentNegotiationManagerFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addMediaTypes() throws Exception {
|
public void addMediaTypes() throws Exception {
|
||||||
Properties mediaTypes = new Properties();
|
Map<String, MediaType> mediaTypes = new HashMap<String, MediaType>();
|
||||||
mediaTypes.put("json", MediaType.APPLICATION_JSON_VALUE);
|
mediaTypes.put("json", MediaType.APPLICATION_JSON);
|
||||||
this.factoryBean.setMediaTypes(mediaTypes);
|
this.factoryBean.addMediaTypes(mediaTypes);
|
||||||
|
|
||||||
this.factoryBean.afterPropertiesSet();
|
this.factoryBean.afterPropertiesSet();
|
||||||
ContentNegotiationManager manager = this.factoryBean.getObject();
|
ContentNegotiationManager manager = this.factoryBean.getObject();
|
||||||
|
|
@ -89,9 +90,9 @@ public class ContentNegotiationManagerFactoryBeanTests {
|
||||||
public void favorParameter() throws Exception {
|
public void favorParameter() throws Exception {
|
||||||
this.factoryBean.setFavorParameter(true);
|
this.factoryBean.setFavorParameter(true);
|
||||||
|
|
||||||
Properties mediaTypes = new Properties();
|
Map<String, MediaType> mediaTypes = new HashMap<String, MediaType>();
|
||||||
mediaTypes.put("json", MediaType.APPLICATION_JSON_VALUE);
|
mediaTypes.put("json", MediaType.APPLICATION_JSON);
|
||||||
this.factoryBean.setMediaTypes(mediaTypes);
|
this.factoryBean.addMediaTypes(mediaTypes);
|
||||||
|
|
||||||
this.factoryBean.afterPropertiesSet();
|
this.factoryBean.afterPropertiesSet();
|
||||||
ContentNegotiationManager manager = this.factoryBean.getObject();
|
ContentNegotiationManager manager = this.factoryBean.getObject();
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.web.servlet.config.annotation;
|
package org.springframework.web.servlet.config.annotation;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
@ -36,7 +37,9 @@ import org.springframework.web.accept.ContentNegotiationManagerFactoryBean;
|
||||||
*/
|
*/
|
||||||
public class ContentNegotiationConfigurer {
|
public class ContentNegotiationConfigurer {
|
||||||
|
|
||||||
private ContentNegotiationManagerFactoryBean factoryBean = new ContentNegotiationManagerFactoryBean();
|
private final ContentNegotiationManagerFactoryBean factoryBean = new ContentNegotiationManagerFactoryBean();
|
||||||
|
|
||||||
|
private final Map<String, MediaType> mediaTypes = new HashMap<String, MediaType>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,7 +67,7 @@ public class ContentNegotiationConfigurer {
|
||||||
* still be used in conjunction with {@link #favorPathExtension(boolean)}.
|
* still be used in conjunction with {@link #favorPathExtension(boolean)}.
|
||||||
*/
|
*/
|
||||||
public ContentNegotiationConfigurer mediaType(String extension, MediaType mediaType) {
|
public ContentNegotiationConfigurer mediaType(String extension, MediaType mediaType) {
|
||||||
this.factoryBean.getMediaTypes().put(extension, mediaType);
|
this.mediaTypes.put(extension, mediaType);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +78,7 @@ public class ContentNegotiationConfigurer {
|
||||||
*/
|
*/
|
||||||
public ContentNegotiationConfigurer mediaTypes(Map<String, MediaType> mediaTypes) {
|
public ContentNegotiationConfigurer mediaTypes(Map<String, MediaType> mediaTypes) {
|
||||||
if (mediaTypes != null) {
|
if (mediaTypes != null) {
|
||||||
this.factoryBean.getMediaTypes().putAll(mediaTypes);
|
this.mediaTypes.putAll(mediaTypes);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +89,7 @@ public class ContentNegotiationConfigurer {
|
||||||
* still be used in conjunction with {@link #favorPathExtension(boolean)}.
|
* still be used in conjunction with {@link #favorPathExtension(boolean)}.
|
||||||
*/
|
*/
|
||||||
public ContentNegotiationConfigurer replaceMediaTypes(Map<String, MediaType> mediaTypes) {
|
public ContentNegotiationConfigurer replaceMediaTypes(Map<String, MediaType> mediaTypes) {
|
||||||
this.factoryBean.getMediaTypes().clear();
|
this.mediaTypes.clear();
|
||||||
mediaTypes(mediaTypes);
|
mediaTypes(mediaTypes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -157,6 +160,9 @@ public class ContentNegotiationConfigurer {
|
||||||
* Return the configured {@link ContentNegotiationManager} instance
|
* Return the configured {@link ContentNegotiationManager} instance
|
||||||
*/
|
*/
|
||||||
protected ContentNegotiationManager getContentNegotiationManager() throws Exception {
|
protected ContentNegotiationManager getContentNegotiationManager() throws Exception {
|
||||||
|
if (!this.mediaTypes.isEmpty()) {
|
||||||
|
this.factoryBean.addMediaTypes(mediaTypes);
|
||||||
|
}
|
||||||
this.factoryBean.afterPropertiesSet();
|
this.factoryBean.afterPropertiesSet();
|
||||||
return this.factoryBean.getObject();
|
return this.factoryBean.getObject();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.activation.FileTypeMap;
|
import javax.activation.FileTypeMap;
|
||||||
|
|
@ -196,7 +197,9 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setMediaTypes(Map<String, String> mediaTypes) {
|
public void setMediaTypes(Map<String, String> mediaTypes) {
|
||||||
if (mediaTypes != null) {
|
if (mediaTypes != null) {
|
||||||
this.cnManagerFactoryBean.getMediaTypes().putAll(mediaTypes);
|
Properties props = new Properties();
|
||||||
|
props.putAll(mediaTypes);
|
||||||
|
this.cnManagerFactoryBean.setMediaTypes(props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue