private ContentNegotiatingViewResolver initContentNegotiatingViewResolver(View[] defaultViews) { // ContentNegotiatingResolver in the registry: elevate its precedence! this.order = (this.order != null ? this.order : Ordered.HIGHEST_PRECEDENCE); if (this.contentNegotiatingResolver != null) { if (!ObjectUtils.isEmpty(defaultViews) && !CollectionUtils.isEmpty(this.contentNegotiatingResolver.getDefaultViews())) { List<View> views = new ArrayList<>(this.contentNegotiatingResolver.getDefaultViews()); views.addAll(Arrays.asList(defaultViews)); this.contentNegotiatingResolver.setDefaultViews(views); } } else { this.contentNegotiatingResolver = new ContentNegotiatingViewResolver(); this.contentNegotiatingResolver.setDefaultViews(Arrays.asList(defaultViews)); this.contentNegotiatingResolver.setViewResolvers(this.viewResolvers); if (this.contentNegotiationManager != null) { this.contentNegotiatingResolver.setContentNegotiationManager(this.contentNegotiationManager); } } return this.contentNegotiatingResolver; }
@Override @Nullable public View resolveViewName(String viewName, Locale locale) throws Exception { RequestAttributes attrs = RequestContextHolder.getRequestAttributes(); Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes"); List<MediaType> requestedMediaTypes = getMediaTypes(((ServletRequestAttributes) attrs).getRequest()); if (requestedMediaTypes != null) { List<View> candidateViews = getCandidateViews(viewName, locale, requestedMediaTypes); View bestView = getBestView(candidateViews, requestedMediaTypes, attrs); if (bestView != null) { return bestView; } } String mediaTypeInfo = logger.isDebugEnabled() && requestedMediaTypes != null ? " given " + requestedMediaTypes.toString() : ""; if (this.useNotAcceptableStatusCode) { if (logger.isDebugEnabled()) { logger.debug("Using 406 NOT_ACCEPTABLE" + mediaTypeInfo); } return NOT_ACCEPTABLE_VIEW; } else { logger.debug("View remains unresolved" + mediaTypeInfo); return null; } }
/** * Enable use of a {@link ContentNegotiatingViewResolver} to front all other * configured view resolvers and select among all selected Views based on * media types requested by the client (e.g. in the Accept header). * <p>If invoked multiple times the provided default views will be added to * any other default views that may have been configured already. * @see ContentNegotiatingViewResolver#setDefaultViews */ public void enableContentNegotiation(boolean useNotAcceptableStatus, View... defaultViews) { ContentNegotiatingViewResolver vr = initContentNegotiatingViewResolver(defaultViews); vr.setUseNotAcceptableStatusCode(useNotAcceptableStatus); }
@Test public void resolveViewNameWithInvalidAcceptHeader() throws Exception { request.addHeader("Accept", "application"); ViewResolver viewResolverMock = mock(ViewResolver.class); viewResolver.setViewResolvers(Collections.singletonList(viewResolverMock)); viewResolver.afterPropertiesSet(); View result = viewResolver.resolveViewName("test", Locale.ENGLISH); assertNull(result); }
@Test public void nestedViewResolverIsNotSpringBean() throws Exception { StaticWebApplicationContext webAppContext = new StaticWebApplicationContext(); webAppContext.setServletContext(new MockServletContext()); webAppContext.refresh(); InternalResourceViewResolver nestedResolver = new InternalResourceViewResolver(); nestedResolver.setApplicationContext(webAppContext); nestedResolver.setViewClass(InternalResourceView.class); viewResolver.setViewResolvers(new ArrayList<>(Arrays.asList(nestedResolver))); FixedContentNegotiationStrategy fixedStrategy = new FixedContentNegotiationStrategy(MediaType.TEXT_HTML); viewResolver.setContentNegotiationManager(new ContentNegotiationManager(fixedStrategy)); viewResolver.afterPropertiesSet(); String viewName = "view"; Locale locale = Locale.ENGLISH; View result = viewResolver.resolveViewName(viewName, locale); assertNotNull("Invalid view", result); }
@Bean public ViewResolver setupViewResolver(ContentNegotiationManager manager){ List<ViewResolver> viewResolvers = new ArrayList<>(); viewResolvers.add(thymeleafViewResolver()); ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setViewResolvers(viewResolvers); resolver.setContentNegotiationManager(manager); return resolver; }
new HeaderContentNegotiationStrategy(), new FixedContentNegotiationStrategy(MediaType.TEXT_HTML)); ContentNegotiatingViewResolver cnViewResolver = new ContentNegotiatingViewResolver(); cnViewResolver.setDefaultViews(viewList); cnViewResolver.setContentNegotiationManager(manager); cnViewResolver.afterPropertiesSet();
@Test public void resolveViewNameWithAcceptHeader() throws Exception { request.addHeader("Accept", "application/vnd.ms-excel"); Map<String, MediaType> mapping = Collections.singletonMap("xls", MediaType.valueOf("application/vnd.ms-excel")); MappingMediaTypeFileExtensionResolver extensionsResolver = new MappingMediaTypeFileExtensionResolver(mapping); ContentNegotiationManager manager = new ContentNegotiationManager(new HeaderContentNegotiationStrategy()); manager.addFileExtensionResolvers(extensionsResolver); viewResolver.setContentNegotiationManager(manager); ViewResolver viewResolverMock = mock(ViewResolver.class); viewResolver.setViewResolvers(Collections.singletonList(viewResolverMock)); View viewMock = mock(View.class, "application_xls"); String viewName = "view"; Locale locale = Locale.ENGLISH; given(viewResolverMock.resolveViewName(viewName, locale)).willReturn(null); given(viewResolverMock.resolveViewName(viewName + ".xls", locale)).willReturn(viewMock); given(viewMock.getContentType()).willReturn("application/vnd.ms-excel"); View result = viewResolver.resolveViewName(viewName, locale); assertSame("Invalid view", viewMock, result); }
final ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver(); contentNegotiatingViewResolver.setOrder(1); contentNegotiatingViewResolver.setFavorPathExtension(true); contentNegotiatingViewResolver.setFavorParameter(true); contentNegotiatingViewResolver.setIgnoreAcceptHeader(false); final Map<String, String> mediaTypes = new HashMap<String, String>(); mediaTypes.put("json", "application/x-json"); mediaTypes.put("xml", "text/xml"); mediaTypes.put("xml", "application/xml"); contentNegotiatingViewResolver.setMediaTypes(mediaTypes); final List<View> defaultViews = new ArrayList<View>(); defaultViews.add(jsonView()); defaultViews.add(xmlView()); contentNegotiatingViewResolver.setDefaultViews(defaultViews); return contentNegotiatingViewResolver;
@Bean public ContentNegotiatingViewResolver contentNegotiatingViewResolver() { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); Map<String, String> mediaTypes = new HashMap<String, String>(); mediaTypes.put("xml", "application/xml"); resolver.setMediaTypes(mediaTypes); List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>(); viewResolvers.add(new BeanNameViewResolver()); resolver.setViewResolvers(viewResolvers); return resolver; }
@Test public void resolveViewNoMatchUseUnacceptableStatus() throws Exception { viewResolver.setUseNotAcceptableStatusCode(true); request.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9"); ViewResolver viewResolverMock = mock(ViewResolver.class); viewResolver.setViewResolvers(Collections.singletonList(viewResolverMock)); viewResolver.afterPropertiesSet(); View viewMock = mock(View.class, "application_xml"); String viewName = "view"; Locale locale = Locale.ENGLISH; given(viewResolverMock.resolveViewName(viewName, locale)).willReturn(viewMock); given(viewMock.getContentType()).willReturn("application/pdf"); View result = viewResolver.resolveViewName(viewName, locale); assertNotNull("Invalid view", result); MockHttpServletResponse response = new MockHttpServletResponse(); result.render(null, request, response); assertEquals("Invalid status code set", 406, response.getStatus()); }
@Before public void createViewResolver() { StaticWebApplicationContext wac = new StaticWebApplicationContext(); wac.setServletContext(new MockServletContext()); wac.refresh(); viewResolver = new ContentNegotiatingViewResolver(); viewResolver.setApplicationContext(wac); request = new MockHttpServletRequest("GET", "/test"); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); }
public void setViewResolvers(List<ViewResolver> viewResolvers) { this.viewResolvers = viewResolvers; super.setViewResolvers(viewResolvers); }
public void setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager){ this.contentNegotiationManager = contentNegotiationManager; super.setContentNegotiationManager(contentNegotiationManager); }
@Test public void getMediaTypeAcceptHeaderWithProduces() throws Exception { Set<MediaType> producibleTypes = Collections.singleton(MediaType.APPLICATION_XHTML_XML); request.setAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, producibleTypes); request.addHeader("Accept", "text/html,application/xml;q=0.9,application/xhtml+xml,*/*;q=0.8"); viewResolver.afterPropertiesSet(); List<MediaType> result = viewResolver.getMediaTypes(request); assertEquals("Invalid content type", new MediaType("application", "xhtml+xml"), result.get(0)); }
@Test public void testViewResolutionWithContentNegotiation() throws Exception { loadBeanDefinitions("mvc-config-view-resolution-content-negotiation.xml"); ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class); assertNotNull(compositeResolver); assertEquals(1, compositeResolver.getViewResolvers().size()); assertEquals(Ordered.HIGHEST_PRECEDENCE, compositeResolver.getOrder()); List<ViewResolver> resolvers = compositeResolver.getViewResolvers(); assertEquals(ContentNegotiatingViewResolver.class, resolvers.get(0).getClass()); ContentNegotiatingViewResolver cnvr = (ContentNegotiatingViewResolver) resolvers.get(0); assertEquals(6, cnvr.getViewResolvers().size()); assertEquals(1, cnvr.getDefaultViews().size()); assertTrue(cnvr.isUseNotAcceptableStatusCode()); String beanName = "contentNegotiationManager"; DirectFieldAccessor accessor = new DirectFieldAccessor(cnvr); ContentNegotiationManager manager = (ContentNegotiationManager) accessor.getPropertyValue(beanName); assertNotNull(manager); assertSame(manager, this.appContext.getBean(ContentNegotiationManager.class)); assertSame(manager, this.appContext.getBean("mvcContentNegotiationManager")); }
@Test public void contentNegotiationAddsDefaultViewRegistrations() { MappingJackson2JsonView view1 = new MappingJackson2JsonView(); this.registry.enableContentNegotiation(view1); ContentNegotiatingViewResolver resolver1 = checkAndGetResolver(ContentNegotiatingViewResolver.class); assertEquals(Arrays.asList(view1), resolver1.getDefaultViews()); MarshallingView view2 = new MarshallingView(); this.registry.enableContentNegotiation(view2); ContentNegotiatingViewResolver resolver2 = checkAndGetResolver(ContentNegotiatingViewResolver.class); assertEquals(Arrays.asList(view1, view2), resolver2.getDefaultViews()); assertSame(resolver1, resolver2); }
public List<MediaType> getMediaTypes(HttpServletRequest request) { return super.getMediaTypes(request); }
@Test public void resolveViewNameWithRequestParameter() throws Exception { request.addParameter("format", "xls"); Map<String, MediaType> mapping = Collections.singletonMap("xls", MediaType.valueOf("application/vnd.ms-excel")); ParameterContentNegotiationStrategy paramStrategy = new ParameterContentNegotiationStrategy(mapping); viewResolver.setContentNegotiationManager(new ContentNegotiationManager(paramStrategy)); ViewResolver viewResolverMock = mock(ViewResolver.class); viewResolver.setViewResolvers(Collections.singletonList(viewResolverMock)); viewResolver.afterPropertiesSet(); View viewMock = mock(View.class, "application_xls"); String viewName = "view"; Locale locale = Locale.ENGLISH; given(viewResolverMock.resolveViewName(viewName, locale)).willReturn(null); given(viewResolverMock.resolveViewName(viewName + ".xls", locale)).willReturn(viewMock); given(viewMock.getContentType()).willReturn("application/vnd.ms-excel"); View result = viewResolver.resolveViewName(viewName, locale); assertSame("Invalid view", viewMock, result); }
@Bean public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) { // Define the view resolvers List<ViewResolver> resolvers = new ArrayList<ViewResolver>(); resolvers.add(new JsonViewResolver()); // Create the CNVR plugging in the resolvers and the content-negotiation manager ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setViewResolvers(resolvers); resolver.setContentNegotiationManager(manager); return resolver; } }