# ContentNegotiatingViewResolver
### Dependencies

### Knowledge
* Resolve a view based on the request file name/Accept header.
* Doesn't resolve views itself, **delegates** to other `ViewResolvers`.
* There resolvers are picked up automatically from the application context.
* `Order` should be set properly.
* Uses `media type` to select a `View` for a request.
* `media type` is determined by `ContentNegotiationManager`.
* `defaultViews` allows you to override the views provided by the view resolvers.

#### Fields
* `contentNegotiationManager`: determine the `media type`
* `useNotAcceptableStatusCode`: indicate whether a `406 Not Acceptable` should be returned if no suitable view can be found.
* `defaultViews`: use when a more specific view cannot be obtained.
* `viewResolvers`: `View Resolvers` to be wrapped by this view resolver.
* `order`: order in ViewResolver chaining
#### Methods
* `initServletContext`: obtain matching `ViewResolvers` by `BeanFactoryUtils` and add them to `viewResolvers` and initialize these `ViewResolvers` and sort them.
* `afterPropertiesSet`: build `contentNegotiationManager`
* `resolveViewName`: obtain `media type` from request and select the best matching `View`. If `useNotAcceptableStatusCode` is set, return `NOT_ACCEPTABLE_VIEW`, else return `null`.
* `getMediaTypes`: obtain `acceptableMediaTypes` from `contentNegotiationManager` and obtain `producibleMediaTypes` from request and find `compatibleMediaTypes(Set)`, then transform it into a `ArrayList`, sort it by specificity and quality and return it finally.
* `getCandidateViews`: obtain `candidateViews` by `viewResolvers`'s `resolveViewName` method. Then for each `requestedMediaType`, get `fileExtensions` by `contentNegotiationManager`'s `resolveFileExtensions` method. And then resolve the `viewNameWithExtension` by `ViewResolvers`.
* `getBestView`: if the `candidateView` is `RedirectView`, then return this view. For each `requestedMediaType`, from `candidateViews`, find the view **Compatible With** the content type and return. If not found, return `null`.