SPR-8611 Add detection of RedirectView when selecting the best view in ContentNegotiatingViewResolver.
This commit is contained in:
parent
7bf44f06a0
commit
37d22ad039
|
|
@ -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…
Reference in New Issue