Implementation of {@link ViewResolver} that resolves a view based on the request file name or {@code Accept} header.
The {@code ContentNegotiatingViewResolver} does not resolve views itself, but delegates to other {@link ViewResolver}s. By default, these other view resolvers are picked up automatically from the application context, though they can also be set explicitly by using the {@link #setViewResolvers(List) viewResolvers} property.Note that in order for this view resolver to work properly, the {@link #setOrder(int) order}property needs to be set to a higher precedence than the others (the default is {@link Ordered#HIGHEST_PRECEDENCE}.)
This view resolver uses the requested {@linkplain MediaType media type} to select a suitable {@link View} for arequest. This media type is determined by using the following criteria:
- If the requested path has a file extension and if the {@link #setFavorPathExtension} property is{@code true}, the {@link #setMediaTypes(Map) mediaTypes} property is inspected for a matching media type.
- If the request contains a parameter defining the extension and if the {@link #setFavorParameter}property is
true
, the {@link #setMediaTypes(Map) mediaTypes} property is inspected for a matchingmedia type. The default name of the parameter is format
and it can be configured using the {@link #setParameterName(String) parameterName} property. - If there is no match in the {@link #setMediaTypes(Map) mediaTypes} property and if the Java ActivationFramework (JAF) is both {@linkplain #setUseJaf enabled} and present on the classpath,{@link FileTypeMap#getContentType(String)} is used instead.
- If the previous steps did not result in a media type, and {@link #setIgnoreAcceptHeader ignoreAcceptHeader} is {@code false}, the request {@code Accept} header isused.
Once the requested media type has been determined, this resolver queries each delegate view resolver for a {@link View} and determines if the requested media type is {@linkplain MediaType#includes(MediaType) compatible}with the view's {@linkplain View#getContentType() content type}). The most compatible view is returned.
Additionally, this view resolver exposes the {@link #setDefaultViews(List) defaultViews} property, allowing you tooverride the views provided by the view resolvers. Note that these default views are offered as candicates, and still need have the content type requested (via file extension, parameter, or {@code Accept} header, described above).You can also set the {@linkplain #setDefaultContentType(MediaType) default content type} directly, which will bereturned when the other mechanisms ( {@code Accept} header, file extension or parameter) do not result in a match.
For example, if the request path is {@code /view.html}, this view resolver will look for a view that has the {@code text/html} content type (based on the {@code html} file extension). A request for {@code /view} with a {@code text/html} request {@code Accept} header has the same result.
@author Arjen Poutsma
@author Juergen Hoeller
@since 3.0
@see ViewResolver
@see InternalResourceViewResolver
@see BeanNameViewResolver