ModelAndViewContainer related refinements

This commit is contained in:
Rossen Stoyanchev
2011-04-07 18:09:28 +00:00
parent 3d8b476f58
commit 6fe0ff9e7b
47 changed files with 547 additions and 1073 deletions

View File

@@ -32,9 +32,7 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
@@ -48,6 +46,7 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.annotation.support.ModelMethodProcessor;
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* Text fixture for {@link ModelFactory} unit tests.
@@ -64,6 +63,8 @@ public class ModelFactoryTests {
private InvocableHandlerMethod requestMethod;
private ModelAndViewContainer mavContainer;
@Before
public void setUp() throws Exception {
Object handler = new ModelHandler();
@@ -73,38 +74,39 @@ public class ModelFactoryTests {
this.sessionAttributeStore = new DefaultSessionAttributeStore();
this.handlerSessionAttributeStore = new SessionAttributesHandler(handler.getClass(), sessionAttributeStore);
this.mavContainer = new ModelAndViewContainer();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest());
}
@Test
public void createModel() throws Exception {
ModelMap model = createFactory(new ModelHandler(), "model", Model.class).createModel(webRequest, requestMethod);
assertEquals(Boolean.TRUE, model.get("model"));
createFactory(new ModelHandler(), "model", Model.class).initModel(webRequest, mavContainer, requestMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("model"));
}
@Test
public void createModelWithName() throws Exception {
ModelMap model = createFactory(new ModelHandler(), "modelWithName").createModel(webRequest, requestMethod);
assertEquals(Boolean.TRUE, model.get("name"));
createFactory(new ModelHandler(), "modelWithName").initModel(webRequest, mavContainer, requestMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("name"));
}
@Test
public void createModelWithDefaultName() throws Exception {
ModelMap model = createFactory(new ModelHandler(), "modelWithDefaultName").createModel(webRequest, requestMethod);
assertEquals(Boolean.TRUE, model.get("boolean"));
createFactory(new ModelHandler(), "modelWithDefaultName").initModel(webRequest, mavContainer, requestMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("boolean"));
}
@Test
public void createModelWithExistingName() throws Exception {
ModelMap model = createFactory(new ModelHandler(), "modelWithName").createModel(webRequest, requestMethod);
assertEquals(Boolean.TRUE, model.get("name"));
createFactory(new ModelHandler(), "modelWithName").initModel(webRequest, mavContainer, requestMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("name"));
}
@Test
public void createModelWithNullAttribute() throws Exception {
ModelMap model = createFactory(new ModelHandler(), "modelWithNullAttribute").createModel(webRequest, requestMethod);
assertTrue(model.containsKey("name"));
assertNull(model.get("name"));
createFactory(new ModelHandler(), "modelWithNullAttribute").initModel(webRequest, mavContainer, requestMethod);
assertTrue(mavContainer.containsAttribute("name"));
assertNull(mavContainer.getAttribute("name"));
}
@Test
@@ -114,8 +116,8 @@ public class ModelFactoryTests {
// Query attribute to associate it with the handler type
assertTrue(handlerSessionAttributeStore.isHandlerSessionAttribute("sessionAttr", null));
ModelMap model = createFactory(new ModelHandler(), "model", Model.class).createModel(webRequest, requestMethod);
assertEquals("sessionAttrValue", model.get("sessionAttr"));
createFactory(new ModelHandler(), "model", Model.class).initModel(webRequest, mavContainer, requestMethod);
assertEquals("sessionAttrValue", mavContainer.getAttribute("sessionAttr"));
}
@Test
@@ -128,8 +130,7 @@ public class ModelFactoryTests {
String attrName = "attr1";
Object attrValue = new Object();
ModelMap actualModel = new ExtendedModelMap();
actualModel.addAttribute(attrName, attrValue);
mavContainer.addAttribute(attrName, attrValue);
WebDataBinder dataBinder = new WebDataBinder(attrValue, attrName);
@@ -138,11 +139,11 @@ public class ModelFactoryTests {
replay(binderFactory);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, sessionAttributeStore);
modelFactory.updateAttributes(webRequest, new SimpleSessionStatus(), actualModel, null);
modelFactory.updateModel(webRequest, mavContainer, new SimpleSessionStatus());
assertEquals(attrValue, actualModel.remove(attrName));
assertSame(dataBinder.getBindingResult(), actualModel.remove(bindingResultKey(attrName)));
assertEquals(0, actualModel.size());
assertEquals(attrValue, mavContainer.getModel().remove(attrName));
assertSame(dataBinder.getBindingResult(), mavContainer.getModel().remove(bindingResultKey(attrName)));
assertEquals(0, mavContainer.getModel().size());
verify(binderFactory);
}

View File

@@ -24,14 +24,12 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.annotation.support.ErrorsMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* Test fixture for {@link ErrorsMethodArgumentResolver} unit tests.
@@ -66,15 +64,15 @@ public class ErrorsMethodHandlerArgumentResolverTests {
WebDataBinder dataBinder = new WebDataBinder(new Object(), "attr");
BindingResult bindingResult = dataBinder.getBindingResult();
ModelMap model = new ExtendedModelMap();
model.addAttribute("ignore1", "value1");
model.addAttribute("ignore2", "value2");
model.addAttribute("ignore3", "value3");
model.addAttribute("ignore4", "value4");
model.addAttribute("ignore5", "value5");
model.addAllAttributes(bindingResult.getModel()); // Predictable iteration order of model keys important!
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAttribute("ignore1", "value1");
mavContainer.addAttribute("ignore2", "value2");
mavContainer.addAttribute("ignore3", "value3");
mavContainer.addAttribute("ignore4", "value4");
mavContainer.addAttribute("ignore5", "value5");
mavContainer.addAllAttributes(bindingResult.getModel()); // Predictable iteration order of model keys important!
Object actual = resolver.resolveArgument(errorsParam, model, webRequest, null);
Object actual = resolver.resolveArgument(errorsParam, mavContainer, webRequest, null);
assertSame(actual, bindingResult);
}
@@ -89,14 +87,14 @@ public class ErrorsMethodHandlerArgumentResolverTests {
WebDataBinder binder2 = new WebDataBinder(target1, "attr2");
BindingResult bindingResult2 = binder2.getBindingResult();
ModelMap model = new ExtendedModelMap();
model.addAttribute("attr1", target1);
model.addAttribute("attr2", target2);
model.addAttribute("filler", "fillerValue");
model.addAllAttributes(bindingResult1.getModel());
model.addAllAttributes(bindingResult2.getModel());
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAttribute("attr1", target1);
mavContainer.addAttribute("attr2", target2);
mavContainer.addAttribute("filler", "fillerValue");
mavContainer.addAllAttributes(bindingResult1.getModel());
mavContainer.addAllAttributes(bindingResult2.getModel());
Object actual = resolver.resolveArgument(errorsParam, model, webRequest, null);
Object actual = resolver.resolveArgument(errorsParam, mavContainer, webRequest, null);
assertSame("Should resolve to the latest BindingResult added", actual, bindingResult2);
}
@@ -106,16 +104,16 @@ public class ErrorsMethodHandlerArgumentResolverTests {
WebDataBinder dataBinder = new WebDataBinder(new Object(), "attr");
BindingResult bindingResult = dataBinder.getBindingResult();
ModelMap model = new ExtendedModelMap();
model.addAllAttributes(bindingResult.getModel());
model.addAttribute("ignore1", "value1");
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(bindingResult.getModel());
mavContainer.addAttribute("ignore1", "value1");
resolver.resolveArgument(errorsParam, model, webRequest, null);
resolver.resolveArgument(errorsParam, mavContainer, webRequest, null);
}
@Test(expected=IllegalStateException.class)
public void noBindingResult() throws Exception {
resolver.resolveArgument(errorsParam, new ExtendedModelMap(), webRequest, null);
resolver.resolveArgument(errorsParam, new ModelAndViewContainer(), webRequest, null);
}
@SuppressWarnings("unused")

View File

@@ -42,8 +42,6 @@ import org.junit.Test;
import org.springframework.beans.TestBean;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
@@ -77,7 +75,7 @@ public class ModelAttributeMethodProcessorTests {
private MethodParameter notAnnotatedReturnParam;
private ModelMap model;
private ModelAndViewContainer mavContainer;
private NativeWebRequest webRequest;
@@ -97,7 +95,7 @@ public class ModelAttributeMethodProcessorTests {
this.annotatedReturnParam = new MethodParameter(getClass().getDeclaredMethod("annotatedReturnValue"), -1);
this.notAnnotatedReturnParam = new MethodParameter(getClass().getDeclaredMethod("notAnnotatedReturnValue"), -1);
model = new ExtendedModelMap();
mavContainer = new ModelAndViewContainer();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest());
}
@@ -139,7 +137,7 @@ public class ModelAttributeMethodProcessorTests {
private void createBinderFromModelAttr(String expectedAttrName, MethodParameter param) throws Exception {
Object target = new TestBean();
model.addAttribute(expectedAttrName, target);
mavContainer.addAttribute(expectedAttrName, target);
WebDataBinder dataBinder = new WebRequestDataBinder(null);
@@ -147,7 +145,7 @@ public class ModelAttributeMethodProcessorTests {
expect(binderFactory.createBinder(webRequest, target, expectedAttrName)).andReturn(dataBinder);
replay(binderFactory);
processor.resolveArgument(param, model, webRequest, binderFactory);
processor.resolveArgument(param, mavContainer, webRequest, binderFactory);
verify(binderFactory);
}
@@ -160,7 +158,7 @@ public class ModelAttributeMethodProcessorTests {
expect(factory.createBinder((NativeWebRequest) anyObject(), notNull(), eq("attrName"))).andReturn(dataBinder);
replay(factory);
processor.resolveArgument(annotatedParam, model, webRequest, factory);
processor.resolveArgument(annotatedParam, mavContainer, webRequest, factory);
verify(factory);
}
@@ -168,14 +166,14 @@ public class ModelAttributeMethodProcessorTests {
@Test
public void bindAndValidate() throws Exception {
Object target = new TestBean();
model.addAttribute("attrName", target);
mavContainer.addAttribute("attrName", target);
StubRequestDataBinder dataBinder = new StubRequestDataBinder(target);
WebDataBinderFactory binderFactory = createMock(WebDataBinderFactory.class);
expect(binderFactory.createBinder(webRequest, target, "attrName")).andReturn(dataBinder);
replay(binderFactory);
processor.resolveArgument(annotatedParam, model, webRequest, binderFactory);
processor.resolveArgument(annotatedParam, mavContainer, webRequest, binderFactory);
assertTrue(dataBinder.isBindInvoked());
assertTrue(dataBinder.isValidateInvoked());
@@ -184,7 +182,7 @@ public class ModelAttributeMethodProcessorTests {
@Test(expected=BindException.class)
public void bindAndFail() throws Exception {
Object target = new TestBean();
model.addAttribute(target);
mavContainer.getModel().addAttribute(target);
StubRequestDataBinder dataBinder = new StubRequestDataBinder(target);
dataBinder.getBindingResult().reject("error");
@@ -192,12 +190,12 @@ public class ModelAttributeMethodProcessorTests {
expect(binderFactory.createBinder(webRequest, target, "testBean")).andReturn(dataBinder);
replay(binderFactory);
processor.resolveArgument(notAnnotatedParam, model, webRequest, binderFactory);
processor.resolveArgument(notAnnotatedParam, mavContainer, webRequest, binderFactory);
}
@Test
public void handleAnnotatedReturnValue() throws Exception {
ModelAndViewContainer mavContainer = new ModelAndViewContainer(model);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
processor.handleReturnValue("expected", annotatedReturnParam, mavContainer, webRequest);
assertEquals("expected", mavContainer.getModel().get("modelAttrName"));
@@ -206,7 +204,7 @@ public class ModelAttributeMethodProcessorTests {
@Test
public void handleNotAnnotatedReturnValue() throws Exception {
TestBean testBean = new TestBean("expected");
ModelAndViewContainer mavContainer = new ModelAndViewContainer(model);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
processor.handleReturnValue(testBean, notAnnotatedReturnParam, mavContainer, webRequest);
assertSame(testBean, mavContainer.getModel().get("testBean"));

View File

@@ -88,13 +88,13 @@ public class ModelMethodProcessorTests {
@Test
public void resolveArgumentValue() throws Exception {
ExtendedModelMap model = new ExtendedModelMap();
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
Object result = resolver.resolveArgument(modelParameter, model, webRequest, null);
assertSame(model, result);
Object result = resolver.resolveArgument(modelParameter, mavContainer, webRequest, null);
assertSame(mavContainer.getModel(), result);
result = resolver.resolveArgument(mapParameter, model, webRequest, null);
assertSame(model, result);
result = resolver.resolveArgument(mapParameter, mavContainer, webRequest, null);
assertSame(mavContainer.getModel(), result);
}
@Test

View File

@@ -78,18 +78,6 @@ public class HandlerMethodArgumentResolverCompositeTests {
this.composite.resolveArgument(paramString, null, null, null);
}
@Test
public void argResolverUsesResponse() throws Exception {
registerResolver(Integer.class, null, true);
assertTrue(this.composite.usesResponseArgument(paramInteger));
}
@Test
public void argResolverDoesntUseResponse() throws Exception {
registerResolver(Integer.class, null, false);
assertFalse(this.composite.usesResponseArgument(paramInteger));
}
protected StubArgumentResolver registerResolver(Class<?> supportedType, Object stubValue, boolean usesResponse) {
StubArgumentResolver resolver = new StubArgumentResolver(supportedType, stubValue, usesResponse);
this.composite.registerArgumentResolver(resolver);

View File

@@ -47,7 +47,7 @@ public class HandlerMethodReturnValueHandlerCompositeTests {
this.paramInteger = new MethodParameter(getClass().getDeclaredMethod("handleInteger"), -1);
this.paramString = new MethodParameter(getClass().getDeclaredMethod("handleString"), -1);
mavContainer = new ModelAndViewContainer(null);
mavContainer = new ModelAndViewContainer();
}
@Test
@@ -81,18 +81,6 @@ public class HandlerMethodReturnValueHandlerCompositeTests {
registerReturnValueHandler(Integer.class, false);
this.composite.handleReturnValue("value", paramString, null, null);
}
@Test
public void returnValueHandlerUsesResponse() throws Exception {
registerReturnValueHandler(Integer.class, true);
assertTrue(this.composite.usesResponseArgument(paramInteger));
}
@Test
public void returnValueHandlerDosntUseResponse() throws Exception {
registerReturnValueHandler(Integer.class, false);
assertFalse(this.composite.usesResponseArgument(paramInteger));
}
protected StubReturnValueHandler registerReturnValueHandler(Class<?> returnType, boolean usesResponse) {
StubReturnValueHandler handler = new StubReturnValueHandler(returnType, usesResponse);

View File

@@ -17,7 +17,6 @@
package org.springframework.web.method.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
@@ -84,14 +83,6 @@ public class InvocableHandlerMethodTests {
assertEquals("intArg", resolver.getResolvedParameterNames().get(0).getParameterName());
}
@Test
public void usesResponseArgResolver() throws Exception {
InvocableHandlerMethod requestMethod = handlerMethod(new Handler(), "usesResponse", int.class);
registerResolver(int.class, 99, true);
assertTrue(requestMethod.usesResponseArgument());
}
private InvocableHandlerMethod handlerMethod(Object handler, String methodName, Class<?>... paramTypes)
throws Exception {
Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes);

View File

@@ -20,10 +20,8 @@ import java.util.ArrayList;
import java.util.List;
import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
/**
* Resolves a method argument from a stub value. Records all resolved parameters.
@@ -58,8 +56,10 @@ public class StubArgumentResolver implements HandlerMethodArgumentResolver {
return parameter.getParameterType().equals(this.supportedType);
}
public Object resolveArgument(MethodParameter parameter, ModelMap model, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
this.resolvedParameters.add(parameter);
return this.stubValue;
}

View File

@@ -53,7 +53,7 @@ public class StubReturnValueHandler implements HandlerMethodReturnValueHandler {
NativeWebRequest webRequest) throws Exception {
this.unhandledReturnValue = returnValue;
if (returnValue != null) {
mavContainer.addModelAttribute(Conventions.getVariableName(returnValue), returnValue);
mavContainer.addAttribute(Conventions.getVariableName(returnValue), returnValue);
}
}