/* * 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.reactive.accept; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.springframework.http.MediaType; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; /** * Factory to create a {@link CompositeContentTypeResolver} and configure it with * one or more {@link RequestedContentTypeResolver} instances with build style * methods. The following table shows methods, resulting strategy instances, and * if in use by default: * *
Property Setter | *Underlying Strategy | *Default Setting | *
---|---|---|
{@link #favorPathExtension} | *{@link PathExtensionContentTypeResolver Path Extension resolver} | *On | *
{@link #favorParameter} | *{@link ParameterContentTypeResolver Parameter resolver} | *Off | *
{@link #ignoreAcceptHeader} | *{@link HeaderContentTypeResolver Header resolver} | *Off | *
{@link #defaultContentType} | *{@link FixedContentTypeResolver Fixed content resolver} | *Not set | *
{@link #defaultContentTypeResolver} | *{@link RequestedContentTypeResolver} | *Not set | *
The order in which resolvers are configured is fixed. Config methods may * only turn individual resolvers on or off. If you need a custom order for any * reason simply instantiate {@code {@link CompositeContentTypeResolver}} * directly. * *
For the path extension and parameter resolvers you may explicitly add * {@link #mediaTypes(Map)}. This will be used to resolve path extensions or a * parameter value such as "json" to a media type such as "application/json". * *
The path extension strategy will also use
* {@link org.springframework.http.MediaTypeFactory} to resolve a path extension
* to a MediaType.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class RequestedContentTypeResolverBuilder {
private boolean favorPathExtension = true;
private boolean favorParameter = false;
private boolean ignoreAcceptHeader = false;
private Map 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 RequestedContentTypeResolverBuilder favorPathExtension(boolean favorPathExtension) {
this.favorPathExtension = favorPathExtension;
return this;
}
/**
* 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 use the
* {@link org.springframework.http.MediaTypeFactory} to resolve path
* extensions.
* @param mediaTypes media type mappings
*/
public RequestedContentTypeResolverBuilder mediaTypes(Map By default this is set to {@code true}.
*/
public RequestedContentTypeResolverBuilder ignoreUnknownPathExtensions(boolean ignore) {
this.ignoreUnknownPathExtensions = ignore;
return this;
}
/**
* When {@link #favorPathExtension favorPathExtension} is set, this
* property determines whether to use only registered {@code MediaType} mappings
* to resolve a path extension to a specific MediaType.
* By default this is not set in which case
* {@code PathExtensionContentNegotiationStrategy} will use defaults if available.
*/
public RequestedContentTypeResolverBuilder useRegisteredExtensionsOnly(boolean useRegisteredExtensionsOnly) {
this.useRegisteredExtensionsOnly = useRegisteredExtensionsOnly;
return this;
}
/**
* Whether a request parameter ("format" by default) should be used to
* determine the requested media type. For this option to work you must
* register {@link #mediaTypes media type mappings}.
* By default this is set to {@code false}.
* @see #parameterName
*/
public RequestedContentTypeResolverBuilder favorParameter(boolean favorParameter) {
this.favorParameter = favorParameter;
return this;
}
/**
* Set the query parameter name to use when {@link #favorParameter} is on.
* The default parameter name is {@code "format"}.
*/
public RequestedContentTypeResolverBuilder parameterName(String parameterName) {
Assert.notNull(parameterName, "parameterName is required");
this.parameterName = parameterName;
return this;
}
/**
* Whether to disable checking the 'Accept' request header.
* By default this value is set to {@code false}.
*/
public RequestedContentTypeResolverBuilder ignoreAcceptHeader(boolean ignoreAcceptHeader) {
this.ignoreAcceptHeader = ignoreAcceptHeader;
return this;
}
/**
* Set the default content type(s) to use when no content type is requested
* in order of priority.
*
* If destinations are present that do not support any of the given media
* types, consider appending {@link MediaType#ALL} at the end.
*
* By default this is not set.
*
* @see #defaultContentTypeResolver
*/
public RequestedContentTypeResolverBuilder defaultContentType(MediaType... contentTypes) {
this.contentTypeResolver = new FixedContentTypeResolver(Arrays.asList(contentTypes));
return this;
}
/**
* Set a custom {@link RequestedContentTypeResolver} to use to determine
* the content type to use when no content type is requested.
* By default this is not set.
* @see #defaultContentType
*/
public RequestedContentTypeResolverBuilder defaultContentTypeResolver(RequestedContentTypeResolver resolver) {
this.contentTypeResolver = resolver;
return this;
}
public CompositeContentTypeResolver build() {
List