提交 66df039b 编写于 作者: R Rossen Stoyanchev

SPR-8698 Support flash attrs and a ModelAndView return value.

Before this change, flash attributes could only be added if via
RedirectAttributes.addFlashAttribute(..) if the method returned
a view name or a View instance. With this change, the above is
supported with a ModelAndView return value as well.
上级 fe0ffec8
......@@ -21,6 +21,8 @@ import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.SmartView;
import org.springframework.web.servlet.View;
/**
* Handles return values of type {@link ModelAndView} copying view and model
......@@ -48,17 +50,29 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
MethodParameter returnType,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception {
if (returnValue != null) {
ModelAndView mav = (ModelAndView) returnValue;
mavContainer.setViewName(mav.getViewName());
if (!mav.isReference()) {
mavContainer.setView(mav.getView());
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
ModelAndView mav = (ModelAndView) returnValue;
if (mav.isReference()) {
String viewName = mav.getViewName();
mavContainer.setViewName(viewName);
if (viewName != null && viewName.startsWith("redirect:")) {
mavContainer.setRedirectModelScenario(true);
}
mavContainer.addAllAttributes(mav.getModel());
}
else {
mavContainer.setRequestHandled(true);
View view = mav.getView();
mavContainer.setView(view);
if (view instanceof SmartView) {
if (((SmartView) view).isRedirectView()) {
mavContainer.setRedirectModelScenario(true);
}
}
}
mavContainer.addAllAttributes(mav.getModel());
}
}
\ No newline at end of file
......@@ -18,6 +18,8 @@ package org.springframework.web.servlet.mvc.method.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
......@@ -26,10 +28,11 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
import org.springframework.web.servlet.view.RedirectView;
/**
......@@ -45,44 +48,90 @@ public class ModelAndViewMethodReturnValueHandlerTests {
private ServletWebRequest webRequest;
private MethodParameter returnParamModelAndView;
@Before
public void setUp() {
public void setUp() throws Exception {
this.handler = new ModelAndViewMethodReturnValueHandler();
this.mavContainer = new ModelAndViewContainer();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest());
this.returnParamModelAndView = getReturnValueParam("modelAndView");
}
@Test
public void supportsReturnType() throws Exception {
assertTrue(handler.supportsReturnType(getReturnValueParam("modelAndView")));
assertTrue(handler.supportsReturnType(returnParamModelAndView));
assertFalse(handler.supportsReturnType(getReturnValueParam("viewName")));
}
@Test
public void handleReturnValueViewName() throws Exception {
public void handleViewReference() throws Exception {
ModelAndView mav = new ModelAndView("viewName", "attrName", "attrValue");
handler.handleReturnValue(mav, getReturnValueParam("modelAndView"), mavContainer, webRequest);
handler.handleReturnValue(mav, returnParamModelAndView, mavContainer, webRequest);
assertEquals("viewName", mavContainer.getView());
assertEquals("attrValue", mavContainer.getModel().get("attrName"));
}
@Test
public void handleReturnValueView() throws Exception {
public void handleViewInstance() throws Exception {
ModelAndView mav = new ModelAndView(new RedirectView(), "attrName", "attrValue");
handler.handleReturnValue(mav, getReturnValueParam("modelAndView"), mavContainer, webRequest);
handler.handleReturnValue(mav, returnParamModelAndView, mavContainer, webRequest);
assertEquals(RedirectView.class, mavContainer.getView().getClass());
assertEquals("attrValue", mavContainer.getModel().get("attrName"));
}
@Test
public void handleReturnValueNull() throws Exception {
handler.handleReturnValue(null, getReturnValueParam("modelAndView"), mavContainer, webRequest);
public void handleNull() throws Exception {
handler.handleReturnValue(null, returnParamModelAndView, mavContainer, webRequest);
assertTrue(mavContainer.isRequestHandled());
}
@Test
public void handleRedirectAttributesWithViewReference() throws Exception {
RedirectAttributesModelMap redirectAttributes = new RedirectAttributesModelMap();
mavContainer.setRedirectModel(redirectAttributes);
ModelAndView mav = new ModelAndView(new RedirectView(), "attrName", "attrValue");
handler.handleReturnValue(mav, returnParamModelAndView, mavContainer, webRequest);
assertEquals(RedirectView.class, mavContainer.getView().getClass());
assertEquals("attrValue", mavContainer.getModel().get("attrName"));
assertSame("RedirectAttributes should be used if controller redirects", redirectAttributes,
mavContainer.getModel());
}
@Test
public void handleRedirectAttributesWithViewInstance() throws Exception {
RedirectAttributesModelMap redirectAttributes = new RedirectAttributesModelMap();
mavContainer.setRedirectModel(redirectAttributes);
ModelAndView mav = new ModelAndView("redirect:viewName", "attrName", "attrValue");
handler.handleReturnValue(mav, returnParamModelAndView, mavContainer, webRequest);
ModelMap model = mavContainer.getModel();
assertEquals("redirect:viewName", mavContainer.getViewName());
assertEquals("attrValue", model.get("attrName"));
assertSame("RedirectAttributes should be used if controller redirects", redirectAttributes, model);
}
@Test
public void handleRedirectAttributesWithoutRedirect() throws Exception {
RedirectAttributesModelMap redirectAttributes = new RedirectAttributesModelMap();
mavContainer.setRedirectModel(redirectAttributes);
ModelAndView mav = new ModelAndView();
handler.handleReturnValue(mav, returnParamModelAndView, mavContainer, webRequest);
ModelMap model = mavContainer.getModel();
assertEquals(null, mavContainer.getView());
assertTrue(mavContainer.getModel().isEmpty());
assertNotSame("RedirectAttributes should not be used if controller doesn't redirect", redirectAttributes, model);
}
private MethodParameter getReturnValueParam(String methodName) throws Exception {
Method method = getClass().getDeclaredMethod(methodName);
return new MethodParameter(method, -1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册