1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2015 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
21
21
22
22
import org .apache .commons .logging .Log ;
23
23
import org .apache .commons .logging .LogFactory ;
24
+
24
25
import org .springframework .beans .BeanUtils ;
25
26
import org .springframework .core .MethodParameter ;
26
27
import org .springframework .core .annotation .AnnotationUtils ;
54
55
*/
55
56
public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResolver , HandlerMethodReturnValueHandler {
56
57
57
- protected Log logger = LogFactory .getLog (this . getClass ());
58
+ protected final Log logger = LogFactory .getLog (getClass ());
58
59
59
60
private final boolean annotationNotRequired ;
60
61
62
+
61
63
/**
62
64
* @param annotationNotRequired if "true", non-simple method arguments and
63
65
* return values are considered model attributes with or without a
@@ -67,10 +69,12 @@ public ModelAttributeMethodProcessor(boolean annotationNotRequired) {
67
69
this .annotationNotRequired = annotationNotRequired ;
68
70
}
69
71
72
+
70
73
/**
71
- * @return true if the parameter is annotated with {@link ModelAttribute}
72
- * or in default resolution mode also if it is not a simple type.
74
+ * Returns {@code true} if the parameter is annotated with {@link ModelAttribute}
75
+ * or in default resolution mode, and also if it is not a simple type.
73
76
*/
77
+ @ Override
74
78
public boolean supportsParameter (MethodParameter parameter ) {
75
79
if (parameter .hasParameterAnnotation (ModelAttribute .class )) {
76
80
return true ;
@@ -92,18 +96,16 @@ else if (this.annotationNotRequired) {
92
96
* and the next method parameter is not of type {@link Errors}.
93
97
* @throws Exception if WebDataBinder initialization fails.
94
98
*/
95
- public final Object resolveArgument (
96
- MethodParameter parameter , ModelAndViewContainer mavContainer ,
97
- NativeWebRequest request , WebDataBinderFactory binderFactory )
98
- throws Exception {
99
+ public final Object resolveArgument (MethodParameter parameter , ModelAndViewContainer mavContainer ,
100
+ NativeWebRequest webRequest , WebDataBinderFactory binderFactory ) throws Exception {
99
101
100
102
String name = ModelFactory .getNameForParameter (parameter );
101
- Object attribute = (mavContainer .containsAttribute (name )) ?
102
- mavContainer .getModel ().get (name ) : createAttribute (name , parameter , binderFactory , request );
103
+ Object attribute = (mavContainer .containsAttribute (name ) ?
104
+ mavContainer .getModel ().get (name ) : createAttribute (name , parameter , binderFactory , webRequest ) );
103
105
104
- WebDataBinder binder = binderFactory .createBinder (request , attribute , name );
106
+ WebDataBinder binder = binderFactory .createBinder (webRequest , attribute , name );
105
107
if (binder .getTarget () != null ) {
106
- bindRequestParameters (binder , request );
108
+ bindRequestParameters (binder , webRequest );
107
109
validateIfApplicable (binder , parameter );
108
110
if (binder .getBindingResult ().hasErrors ()) {
109
111
if (isBindExceptionRequired (binder , parameter )) {
@@ -113,7 +115,6 @@ public final Object resolveArgument(
113
115
}
114
116
115
117
// Add resolved attribute and BindingResult at the end of the model
116
-
117
118
Map <String , Object > bindingResultModel = binder .getBindingResult ().getModel ();
118
119
mavContainer .removeAttributes (bindingResultModel );
119
120
mavContainer .addAllAttributes (bindingResultModel );
@@ -124,16 +125,16 @@ public final Object resolveArgument(
124
125
/**
125
126
* Extension point to create the model attribute if not found in the model.
126
127
* The default implementation uses the default constructor.
127
- * @param attributeName the name of the attribute, never {@code null}
128
- * @param parameter the method parameter
128
+ * @param attributeName the name of the attribute ( never {@code null})
129
+ * @param methodParam the method parameter
129
130
* @param binderFactory for creating WebDataBinder instance
130
131
* @param request the current request
131
- * @return the created model attribute, never {@code null}
132
+ * @return the created model attribute ( never {@code null})
132
133
*/
133
- protected Object createAttribute (String attributeName , MethodParameter parameter ,
134
- WebDataBinderFactory binderFactory , NativeWebRequest request ) throws Exception {
134
+ protected Object createAttribute (String attributeName , MethodParameter methodParam ,
135
+ WebDataBinderFactory binderFactory , NativeWebRequest request ) throws Exception {
135
136
136
- return BeanUtils .instantiateClass (parameter .getParameterType ());
137
+ return BeanUtils .instantiateClass (methodParam .getParameterType ());
137
138
}
138
139
139
140
/**
@@ -147,15 +148,17 @@ protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest requ
147
148
148
149
/**
149
150
* Validate the model attribute if applicable.
150
- * <p>The default implementation checks for {@code @javax.validation.Valid}.
151
+ * <p>The default implementation checks for {@code @javax.validation.Valid},
152
+ * Spring's {@link org.springframework.validation.annotation.Validated},
153
+ * and custom annotations whose name starts with "Valid".
151
154
* @param binder the DataBinder to be used
152
- * @param parameter the method parameter
155
+ * @param methodParam the method parameter
153
156
*/
154
- protected void validateIfApplicable (WebDataBinder binder , MethodParameter parameter ) {
155
- Annotation [] annotations = parameter .getParameterAnnotations ();
156
- for (Annotation annot : annotations ) {
157
- if (annot .annotationType ().getSimpleName ().startsWith ("Valid" )) {
158
- Object hints = AnnotationUtils .getValue (annot );
157
+ protected void validateIfApplicable (WebDataBinder binder , MethodParameter methodParam ) {
158
+ Annotation [] annotations = methodParam .getParameterAnnotations ();
159
+ for (Annotation ann : annotations ) {
160
+ if (ann .annotationType ().getSimpleName ().startsWith ("Valid" )) {
161
+ Object hints = AnnotationUtils .getValue (ann );
159
162
binder .validate (hints instanceof Object [] ? (Object []) hints : new Object [] {hints });
160
163
break ;
161
164
}
@@ -165,14 +168,13 @@ protected void validateIfApplicable(WebDataBinder binder, MethodParameter parame
165
168
/**
166
169
* Whether to raise a {@link BindException} on validation errors.
167
170
* @param binder the data binder used to perform data binding
168
- * @param parameter the method argument
169
- * @return {@code true} if the next method argument is not of type {@link Errors}.
171
+ * @param methodParam the method argument
172
+ * @return {@code true} if the next method argument is not of type {@link Errors}
170
173
*/
171
- protected boolean isBindExceptionRequired (WebDataBinder binder , MethodParameter parameter ) {
172
- int i = parameter .getParameterIndex ();
173
- Class <?>[] paramTypes = parameter .getMethod ().getParameterTypes ();
174
+ protected boolean isBindExceptionRequired (WebDataBinder binder , MethodParameter methodParam ) {
175
+ int i = methodParam .getParameterIndex ();
176
+ Class <?>[] paramTypes = methodParam .getMethod ().getParameterTypes ();
174
177
boolean hasBindingResult = (paramTypes .length > (i + 1 ) && Errors .class .isAssignableFrom (paramTypes [i + 1 ]));
175
-
176
178
return !hasBindingResult ;
177
179
}
178
180
@@ -195,14 +197,13 @@ else if (this.annotationNotRequired) {
195
197
/**
196
198
* Add non-null return values to the {@link ModelAndViewContainer}.
197
199
*/
198
- public void handleReturnValue (
199
- Object returnValue , MethodParameter returnType ,
200
- ModelAndViewContainer mavContainer , NativeWebRequest webRequest )
201
- throws Exception {
200
+ public void handleReturnValue (Object returnValue , MethodParameter returnType ,
201
+ ModelAndViewContainer mavContainer , NativeWebRequest webRequest ) throws Exception {
202
202
203
203
if (returnValue != null ) {
204
204
String name = ModelFactory .getNameForReturnValue (returnValue , returnType );
205
205
mavContainer .addAttribute (name , returnValue );
206
206
}
207
207
}
208
+
208
209
}
0 commit comments