org.springframework.web.accept.ContentNegotiationManagerFactoryBean Maven / Gradle / Ivy
/*
* Copyright 2002-2017 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
*
* http://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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.ServletContextAware;
/**
* Factory to create a {@code ContentNegotiationManager} and configure it with
* one or more {@link ContentNegotiationStrategy} instances.
*
* As of 5.0 you can set the exact strategies to use via
* {@link #setStrategies(List)}.
*
*
As an alternative you can also rely on the set of defaults described below
* which can be turned on or off or customized through the methods of this
* builder:
*
*
*
* Property Setter
* Underlying Strategy
* Default Setting
*
*
* {@link #setFavorPathExtension}
* {@link PathExtensionContentNegotiationStrategy Path Extension strategy}
* On
*
*
* {@link #setFavorParameter favorParameter}
* {@link ParameterContentNegotiationStrategy Parameter strategy}
* Off
*
*
* {@link #setIgnoreAcceptHeader ignoreAcceptHeader}
* {@link HeaderContentNegotiationStrategy Header strategy}
* On
*
*
* {@link #setDefaultContentType defaultContentType}
* {@link FixedContentNegotiationStrategy Fixed content strategy}
* Not set
*
*
* {@link #setDefaultContentTypeStrategy defaultContentTypeStrategy}
* {@link ContentNegotiationStrategy}
* Not set
*
*
*
* Note: if you must use URL-based content type resolution,
* the use of a query parameter is simpler and preferable to the use of a path
* extension since the latter can cause issues with URI variables, path
* parameters, and URI decoding. Consider setting {@link #setFavorPathExtension}
* to {@literal false} or otherwise set the strategies to use explicitly via
* {@link #setStrategies(List)}.
*
* @author Rossen Stoyanchev
* @author Brian Clozel
* @since 3.2
*/
public class ContentNegotiationManagerFactoryBean
implements FactoryBean, ServletContextAware, InitializingBean {
@Nullable
private List strategies;
private boolean favorPathExtension = true;
private boolean favorParameter = false;
private boolean ignoreAcceptHeader = false;
private Map mediaTypes = new HashMap<>();
private boolean ignoreUnknownPathExtensions = true;
@Nullable
private Boolean useRegisteredExtensionsOnly;
private String parameterName = "format";
@Nullable
private ContentNegotiationStrategy defaultNegotiationStrategy;
@Nullable
private ContentNegotiationManager contentNegotiationManager;
@Nullable
private ServletContext servletContext;
/**
* Set the exact list of strategies to use.
* Note: use of this method is mutually exclusive with
* use of all other setters in this class which customize a default, fixed
* set of strategies. See class level doc for more details.
* @param strategies the strategies to use
* @since 5.0
*/
public void setStrategies(@Nullable List strategies) {
this.strategies = (strategies != null ? new ArrayList<>(strategies) : null);
}
/**
* Whether the path extension in the URL path should be used to determine
* the requested media type.
* By default this is set to {@code true} in which case a request
* for {@code /hotels.pdf} will be interpreted as a request for
* {@code "application/pdf"} regardless of the 'Accept' header.
*/
public void setFavorPathExtension(boolean favorPathExtension) {
this.favorPathExtension = favorPathExtension;
}
/**
* Add a mapping from a key, extracted from a path extension or a query
* parameter, to a MediaType. This is required in order for the parameter
* strategy to work. Any extensions explicitly registered here are also
* whitelisted for the purpose of Reflected File Download attack detection
* (see Spring Framework reference documentation for more details on RFD
* attack protection).
*
The path extension strategy will also try to use
* {@link ServletContext#getMimeType} and
* {@link org.springframework.http.MediaTypeFactory} to resolve path extensions.
* @param mediaTypes media type mappings
* @see #addMediaType(String, MediaType)
* @see #addMediaTypes(Map)
*/
public void setMediaTypes(Properties mediaTypes) {
if (!CollectionUtils.isEmpty(mediaTypes)) {
for (Entry