Skip to content

Commit 7aaad37

Browse files
committed
SPR-7327 add <mvc:argument-resolvers> namespace element
1 parent 182b6a4 commit 7aaad37

File tree

4 files changed

+75
-10
lines changed

4 files changed

+75
-10
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,16 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
119119
bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);
120120

121121
ManagedList<?> messageConverters = getMessageConverters(element, source, parserContext);
122+
ManagedList<?> argumentResolvers = getArgumentResolvers(element, source, parserContext);
122123

123124
RootBeanDefinition annAdapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
124125
annAdapterDef.setSource(source);
125126
annAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
126127
annAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
127128
annAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
129+
if (argumentResolvers != null) {
130+
annAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
131+
}
128132
String annAdapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef);
129133

130134
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
@@ -211,6 +215,21 @@ private RuntimeBeanReference getMessageCodesResolver(Element element, Object sou
211215
}
212216
}
213217

218+
private ManagedList<?> getArgumentResolvers(Element element, Object source, ParserContext parserContext) {
219+
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
220+
if (resolversElement != null) {
221+
ManagedList<BeanDefinitionHolder> argumentResolvers = new ManagedList<BeanDefinitionHolder>();
222+
argumentResolvers.setSource(source);
223+
for (Element resolver : DomUtils.getChildElementsByTagName(resolversElement, "bean")) {
224+
BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(resolver);
225+
beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(resolver, beanDef);
226+
argumentResolvers.add(beanDef);
227+
}
228+
return argumentResolvers;
229+
}
230+
return null;
231+
}
232+
214233
private ManagedList<?> getMessageConverters(Element element, Object source, ParserContext parserContext) {
215234
Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
216235
if (convertersElement != null) {

org.springframework.web.servlet/src/main/resources/org/springframework/web/servlet/config/spring-mvc-3.1.xsd

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@
3131
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
3232
<xsd:annotation>
3333
<xsd:documentation><![CDATA[
34+
The HttpMessageConverter bean definition.
35+
]]></xsd:documentation>
36+
</xsd:annotation>
37+
</xsd:element>
38+
</xsd:sequence>
39+
</xsd:complexType>
40+
</xsd:element>
41+
<xsd:element name="argument-resolvers">
42+
<xsd:annotation>
43+
<xsd:documentation><![CDATA[
44+
Configures one or more WebArgumentResolver types to use for resolving custom arguments to handler methods.
45+
Typically implemented to detect special parameter types, resolving well-known argument values for them.
46+
Using this configuration element is optional.
47+
Using it does not override the built-in support for resolving handler method arguments.
48+
]]></xsd:documentation>
49+
</xsd:annotation>
50+
<xsd:complexType>
51+
<xsd:sequence>
52+
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
53+
<xsd:annotation>
54+
<xsd:documentation><![CDATA[
3455
The HttpMessageConverter bean definition.
3556
]]></xsd:documentation>
3657
</xsd:annotation>

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@
2323
import org.junit.Test;
2424
import org.springframework.beans.DirectFieldAccessor;
2525
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
26+
import org.springframework.core.MethodParameter;
2627
import org.springframework.core.io.ClassPathResource;
2728
import org.springframework.http.converter.HttpMessageConverter;
2829
import org.springframework.http.converter.ResourceHttpMessageConverter;
2930
import org.springframework.http.converter.StringHttpMessageConverter;
3031
import org.springframework.validation.MessageCodesResolver;
3132
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
33+
import org.springframework.web.bind.support.WebArgumentResolver;
34+
import org.springframework.web.context.request.NativeWebRequest;
3235
import org.springframework.web.context.support.GenericWebApplicationContext;
3336
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
3437
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver;
@@ -67,6 +70,17 @@ public void testMessageConverters() {
6770
verifyMessageConverters(appContext.getBean(AnnotationMethodHandlerExceptionResolver.class));
6871
}
6972

73+
@Test
74+
public void testArgumentResolvers() {
75+
AnnotationMethodHandlerAdapter adapter = appContext.getBean(AnnotationMethodHandlerAdapter.class);
76+
assertNotNull(adapter);
77+
Object resolvers = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
78+
assertNotNull(resolvers);
79+
assertTrue(resolvers instanceof WebArgumentResolver[]);
80+
assertEquals(2, ((WebArgumentResolver[]) resolvers).length);
81+
assertTrue(((WebArgumentResolver[]) resolvers)[0] instanceof TestWebArgumentResolver);
82+
assertTrue(((WebArgumentResolver[]) resolvers)[1] instanceof TestWebArgumentResolver);
83+
}
7084

7185
private void verifyMessageConverters(Object bean) {
7286
assertNotNull(bean);
@@ -78,17 +92,25 @@ private void verifyMessageConverters(Object bean) {
7892
assertTrue(((HttpMessageConverter<?>[]) converters)[1] instanceof ResourceHttpMessageConverter);
7993
}
8094

81-
private static class TestMessageCodesResolver implements MessageCodesResolver {
95+
}
8296

83-
public String[] resolveMessageCodes(String errorCode, String objectName) {
84-
throw new IllegalStateException("Not expected to be invoked");
85-
}
97+
class TestWebArgumentResolver implements WebArgumentResolver {
8698

87-
@SuppressWarnings("rawtypes")
88-
public String[] resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType) {
89-
throw new IllegalStateException("Not expected to be invoked");
90-
}
99+
public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
100+
return null;
101+
}
102+
103+
}
104+
105+
class TestMessageCodesResolver implements MessageCodesResolver {
106+
107+
public String[] resolveMessageCodes(String errorCode, String objectName) {
108+
return new String[] { "test.foo.bar" };
109+
}
91110

111+
@SuppressWarnings("rawtypes")
112+
public String[] resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType) {
113+
return new String[] { "test.foo.bar" };
92114
}
93115

94116
}

org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-annotation-driven.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
77

88
<mvc:annotation-driven message-codes-resolver="messageCodesResolver">
9+
<mvc:argument-resolvers>
10+
<bean class="org.springframework.web.servlet.config.TestWebArgumentResolver"/>
11+
<bean class="org.springframework.web.servlet.config.TestWebArgumentResolver"/>
12+
</mvc:argument-resolvers>
913
<mvc:message-converters>
1014
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
1115
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
1216
</mvc:message-converters>
1317
</mvc:annotation-driven>
1418

15-
<bean id="messageCodesResolver"
16-
class="org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParserTests$TestMessageCodesResolver"/>
19+
<bean id="messageCodesResolver" class="org.springframework.web.servlet.config.TestMessageCodesResolver"/>
1720

1821
</beans>

0 commit comments

Comments
 (0)