SPR-8611 Add detection of RedirectView when selecting the best view in ContentNegotiatingViewResolver.

master
Rossen Stoyanchev 13 years ago
parent 7bf44f06a0
commit 37d22ad039
  1. 36
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java
  2. 26
      org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java

@ -53,6 +53,7 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationObjectSupport;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.SmartView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.util.UrlPathHelper;
@ -476,29 +477,32 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
}
private View getBestView(List<View> candidateViews, List<MediaType> requestedMediaTypes) {
MediaType bestRequestedMediaType = null;
View bestView = null;
for (MediaType requestedMediaType : requestedMediaTypes) {
for (View candidateView : candidateViews) {
if (candidateView instanceof SmartView) {
SmartView smartView = (SmartView) candidateView;
if (smartView.isRedirectView()) {
if (logger.isDebugEnabled()) {
logger.debug("Returning redirect view [" + candidateView + "]");
}
return candidateView;
}
}
}
for (MediaType mediaType : requestedMediaTypes) {
for (View candidateView : candidateViews) {
if (StringUtils.hasText(candidateView.getContentType())) {
MediaType candidateContentType = MediaType.parseMediaType(candidateView.getContentType());
if (requestedMediaType.includes(candidateContentType)) {
bestRequestedMediaType = requestedMediaType;
bestView = candidateView;
break;
if (mediaType.includes(candidateContentType)) {
if (logger.isDebugEnabled()) {
logger.debug("Returning [" + candidateView + "] based on requested media type '"
+ mediaType + "'");
}
return candidateView;
}
}
}
if (bestView != null) {
if (logger.isDebugEnabled()) {
logger.debug("Returning [" + bestView + "] based on requested media type '" +
bestRequestedMediaType + "'");
}
break;
}
}
return bestView;
return null;
}

@ -402,6 +402,32 @@ public class ContentNegotiatingViewResolverTests {
verify(viewResolverMock, viewMock);
}
@Test
public void resolveViewNameRedirectView() throws Exception {
request.addHeader("Accept", "application/json");
request.setRequestURI("/test");
ViewResolver xmlViewResolver = createMock(ViewResolver.class);
viewResolver.setViewResolvers(Arrays.<ViewResolver>asList(xmlViewResolver, new UrlBasedViewResolver()));
View xmlView = createMock("application_xml", View.class);
View jsonView = createMock("application_json", View.class);
viewResolver.setDefaultViews(Arrays.asList(jsonView));
String viewName = "redirect:anotherTest";
Locale locale = Locale.ENGLISH;
expect(xmlViewResolver.resolveViewName(viewName, locale)).andReturn(xmlView);
expect(jsonView.getContentType()).andReturn("application/json").anyTimes();
replay(xmlViewResolver, xmlView, jsonView);
View actualView = viewResolver.resolveViewName(viewName, locale);
assertEquals("Invalid view", RedirectView.class, actualView.getClass());
verify(xmlViewResolver, xmlView, jsonView);
}
@Test
public void resolveViewNoMatch() throws Exception {
request.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9");

Loading…
Cancel
Save