SPR-8234 Argument resolver and return value handler configuration improvements

This commit is contained in:
Rossen Stoyanchev
2011-04-11 12:37:33 +00:00
parent 68b4687311
commit 313546ad1f
15 changed files with 431 additions and 247 deletions

View File

@@ -19,6 +19,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
@@ -31,10 +33,14 @@ import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
/**
* Test fixture for the configuration in mvc-config-annotation-driven.xml.
@@ -75,17 +81,19 @@ public class AnnotationDrivenBeanDefinitionParserTests {
verifyMessageConverters(appContext.getBean(RequestMappingHandlerMethodExceptionResolver.class), false);
}
@SuppressWarnings("unchecked")
@Test
public void testArgumentResolvers() {
loadBeanDefinitions("mvc-config-argument-resolvers.xml");
RequestMappingHandlerMethodAdapter adapter = appContext.getBean(RequestMappingHandlerMethodAdapter.class);
assertNotNull(adapter);
Object resolvers = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
assertNotNull(resolvers);
assertTrue(resolvers instanceof WebArgumentResolver[]);
assertEquals(2, ((WebArgumentResolver[]) resolvers).length);
assertTrue(((WebArgumentResolver[]) resolvers)[0] instanceof TestWebArgumentResolver);
assertTrue(((WebArgumentResolver[]) resolvers)[1] instanceof TestWebArgumentResolver);
Object value = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
assertNotNull(value);
assertTrue(value instanceof List);
List<HandlerMethodArgumentResolver> resolvers = (List<HandlerMethodArgumentResolver>) value;
assertEquals(2, resolvers.size());
assertTrue(resolvers.get(0) instanceof ServletWebArgumentResolverAdapter);
assertTrue(resolvers.get(1) instanceof TestHandlerMethodArgumentResolver);
}
private void loadBeanDefinitions(String fileName) {
@@ -95,20 +103,20 @@ public class AnnotationDrivenBeanDefinitionParserTests {
appContext.refresh();
}
@SuppressWarnings("unchecked")
private void verifyMessageConverters(Object bean, boolean hasDefaultRegistrations) {
assertNotNull(bean);
Object converters = new DirectFieldAccessor(bean).getPropertyValue("messageConverters");
assertNotNull(converters);
assertTrue(converters instanceof HttpMessageConverter<?>[]);
Object value = new DirectFieldAccessor(bean).getPropertyValue("messageConverters");
assertNotNull(value);
assertTrue(value instanceof List);
List<HttpMessageConverter<?>> converters = (List<HttpMessageConverter<?>>) value;
if (hasDefaultRegistrations) {
assertTrue("Default converters are registered in addition to custom ones",
((HttpMessageConverter<?>[]) converters).length > 2);
assertTrue("Default converters are registered in addition to custom ones", converters.size() > 2);
} else {
assertTrue("Default converters should not be registered",
((HttpMessageConverter<?>[]) converters).length == 2);
assertTrue("Default converters should not be registered", converters.size() == 2);
}
assertTrue(((HttpMessageConverter<?>[]) converters)[0] instanceof StringHttpMessageConverter);
assertTrue(((HttpMessageConverter<?>[]) converters)[1] instanceof ResourceHttpMessageConverter);
assertTrue(converters.get(0) instanceof StringHttpMessageConverter);
assertTrue(converters.get(1) instanceof ResourceHttpMessageConverter);
}
}
@@ -121,6 +129,18 @@ class TestWebArgumentResolver implements WebArgumentResolver {
}
class TestHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
public boolean supportsParameter(MethodParameter parameter) {
return false;
}
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return null;
}
}
class TestMessageCodesResolver implements MessageCodesResolver {
public String[] resolveMessageCodes(String errorCode, String objectName) {

View File

@@ -19,6 +19,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -35,8 +37,10 @@ import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
/**
* Integration tests for the {@link MvcAnnotationDriven} feature specification.
@@ -46,6 +50,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
*/
public class MvcAnnotationDrivenFeatureTests {
@SuppressWarnings("unchecked")
@Test
public void testMessageCodesResolver() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -58,16 +63,17 @@ public class MvcAnnotationDrivenFeatureTests {
MessageCodesResolver resolver = ((ConfigurableWebBindingInitializer) initializer).getMessageCodesResolver();
assertNotNull(resolver);
assertEquals("test.foo.bar", resolver.resolveMessageCodes("foo", "bar")[0]);
Object argResolvers = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
assertNotNull(argResolvers);
WebArgumentResolver[] argResolversArray = (WebArgumentResolver[]) argResolvers;
assertEquals(1, argResolversArray.length);
assertTrue(argResolversArray[0] instanceof TestWebArgumentResolver);
Object value = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
assertNotNull(value);
List<HandlerMethodArgumentResolver> resolvers = (List<HandlerMethodArgumentResolver>) value;
assertEquals(2, resolvers.size());
assertTrue(resolvers.get(0) instanceof ServletWebArgumentResolverAdapter);
assertTrue(resolvers.get(1) instanceof TestHandlerMethodArgumentResolver);
Object converters = new DirectFieldAccessor(adapter).getPropertyValue("messageConverters");
assertNotNull(converters);
HttpMessageConverter<?>[] convertersArray = (HttpMessageConverter<?>[]) converters;
assertTrue("Default converters are registered in addition to the custom one", convertersArray.length > 1);
assertTrue(convertersArray[0] instanceof StringHttpMessageConverter);
List<HttpMessageConverter<?>> convertersArray = (List<HttpMessageConverter<?>>) converters;
assertTrue("Default converters are registered in addition to the custom one", convertersArray.size() > 1);
assertTrue(convertersArray.get(0) instanceof StringHttpMessageConverter);
}
}
@@ -81,7 +87,8 @@ class MvcFeature {
.messageCodesResolver(mvcBeans.messageCodesResolver())
.validator(mvcBeans.validator())
.messageConverters(new StringHttpMessageConverter())
.argumentResolvers(new TestWebArgumentResolver());
.argumentResolvers(new TestWebArgumentResolver())
.argumentResolvers(new TestHandlerMethodArgumentResolver());
}
}

View File

@@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.servlet.RequestDispatcher;
@@ -111,8 +112,8 @@ public class MvcNamespaceTests {
RequestMappingHandlerMethodAdapter adapter = appContext.getBean(RequestMappingHandlerMethodAdapter.class);
assertNotNull(adapter);
HttpMessageConverter<?>[] messageConverters = adapter.getMessageConverters();
assertTrue(messageConverters.length > 0);
List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters();
assertTrue(messageConverters.size() > 0);
assertNotNull(appContext.getBean(FormattingConversionServiceFactoryBean.class));
assertNotNull(appContext.getBean(ConversionService.class));

View File

@@ -26,10 +26,12 @@ import java.awt.Color;
import java.lang.reflect.Method;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.Cookie;
@@ -74,10 +76,11 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
/**
* A test fixture for higher-level {@link RequestMappingHandlerMethodAdapter} tests.
@@ -109,9 +112,12 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
bindingInitializer.setValidator(new StubValidator());
List<HandlerMethodArgumentResolver> customResolvers = new ArrayList<HandlerMethodArgumentResolver>();
customResolvers.add(new ServletWebArgumentResolverAdapter(new ColorArgumentResolver()));
this.handlerAdapter = new RequestMappingHandlerMethodAdapter();
this.handlerAdapter.setWebBindingInitializer(bindingInitializer);
this.handlerAdapter.setCustomArgumentResolvers(new WebArgumentResolver[] { new ColorArgumentResolver() });
this.handlerAdapter.setCustomArgumentResolvers(customResolvers);
GenericWebApplicationContext context = new GenericWebApplicationContext();
context.refresh();

View File

@@ -1079,7 +1079,7 @@ public class ServletHandlerMethodTests {
public void register(GenericWebApplicationContext wac) {
RootBeanDefinition adapterDef = new RootBeanDefinition(RequestMappingHandlerMethodAdapter.class);
ModelAndViewResolver[] mavResolvers = new ModelAndViewResolver[] {new MyModelAndViewResolver()};
adapterDef.getPropertyValues().add("customModelAndViewResolvers", mavResolvers);
adapterDef.getPropertyValues().add("modelAndViewResolvers", mavResolvers);
wac.registerBeanDefinition("handlerAdapter", adapterDef);
}
});

View File

@@ -27,7 +27,9 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
@@ -82,7 +84,10 @@ public class HttpEntityMethodProcessorTests {
@Before
public void setUp() throws Exception {
messageConverter = createMock(HttpMessageConverter.class);
processor = new HttpEntityMethodProcessor(messageConverter);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(messageConverter);
processor = new HttpEntityMethodProcessor(messageConverters);
Method handle1 = getClass().getMethod("handle1", HttpEntity.class, ResponseEntity.class, Integer.TYPE);
httpEntityParam = new MethodParameter(handle1, 0);
@@ -211,7 +216,9 @@ public class HttpEntityMethodProcessorTests {
responseHeaders.set("header", "headerValue");
ResponseEntity<String> returnValue = new ResponseEntity<String>(responseHeaders, HttpStatus.ACCEPTED);
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(new StringHttpMessageConverter());
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new StringHttpMessageConverter());
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(messageConverters);
processor.handleReturnValue(returnValue, responseEntityReturnValue, mavContainer, request);
assertFalse(mavContainer.isResolveView());
@@ -224,7 +231,9 @@ public class HttpEntityMethodProcessorTests {
responseHeaders.set("header", "headerValue");
ResponseEntity<String> returnValue = new ResponseEntity<String>("body", responseHeaders, HttpStatus.ACCEPTED);
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(new StringHttpMessageConverter());
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new StringHttpMessageConverter());
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(messageConverters);
processor.handleReturnValue(returnValue, responseEntityReturnValue, mavContainer, request);
assertFalse(mavContainer.isResolveView());

View File

@@ -27,7 +27,9 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
@@ -45,7 +47,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.support.RequestResponseBodyMethodProcessor;
/**
* @author Arjen Poutsma
@@ -74,7 +75,11 @@ public class RequestResponseBodyMethodProcessorTests {
@Before
public void setUp() throws Exception {
messageConverter = createMock(HttpMessageConverter.class);
processor = new RequestResponseBodyMethodProcessor(messageConverter);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(messageConverter);
processor = new RequestResponseBodyMethodProcessor(messageConverters);
Method handle = getClass().getMethod("handle", String.class, Integer.TYPE);
stringParameter = new MethodParameter(handle, 0);
intParameter = new MethodParameter(handle, 1);

View File

@@ -8,7 +8,7 @@
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.web.servlet.config.TestWebArgumentResolver"/>
<bean class="org.springframework.web.servlet.config.TestWebArgumentResolver"/>
<bean class="org.springframework.web.servlet.config.TestHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>