1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.web.servlet.mvc.method.annotation;
18
19 import java.util.Collections;
20 import java.util.Map;
21 import javax.servlet.ServletRequest;
22
23 import org.springframework.core.MethodParameter;
24 import org.springframework.core.convert.ConversionService;
25 import org.springframework.core.convert.TypeDescriptor;
26 import org.springframework.core.convert.converter.Converter;
27 import org.springframework.util.StringUtils;
28 import org.springframework.validation.DataBinder;
29 import org.springframework.web.bind.ServletRequestDataBinder;
30 import org.springframework.web.bind.WebDataBinder;
31 import org.springframework.web.bind.support.WebDataBinderFactory;
32 import org.springframework.web.context.request.NativeWebRequest;
33 import org.springframework.web.context.request.RequestAttributes;
34 import org.springframework.web.method.annotation.ModelAttributeMethodProcessor;
35 import org.springframework.web.servlet.HandlerMapping;
36
37
38
39
40
41
42
43
44
45
46
47
48 public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor {
49
50
51
52
53
54
55 public ServletModelAttributeMethodProcessor(boolean annotationNotRequired) {
56 super(annotationNotRequired);
57 }
58
59
60
61
62
63
64
65
66
67 @Override
68 protected final Object createAttribute(String attributeName, MethodParameter methodParam,
69 WebDataBinderFactory binderFactory, NativeWebRequest request) throws Exception {
70
71 String value = getRequestValueForAttribute(attributeName, request);
72 if (value != null) {
73 Object attribute = createAttributeFromRequestValue(
74 value, attributeName, methodParam, binderFactory, request);
75 if (attribute != null) {
76 return attribute;
77 }
78 }
79
80 return super.createAttribute(attributeName, methodParam, binderFactory, request);
81 }
82
83
84
85
86
87
88
89
90
91
92 protected String getRequestValueForAttribute(String attributeName, NativeWebRequest request) {
93 Map<String, String> variables = getUriTemplateVariables(request);
94 if (StringUtils.hasText(variables.get(attributeName))) {
95 return variables.get(attributeName);
96 }
97 else if (StringUtils.hasText(request.getParameter(attributeName))) {
98 return request.getParameter(attributeName);
99 }
100 else {
101 return null;
102 }
103 }
104
105 @SuppressWarnings("unchecked")
106 protected final Map<String, String> getUriTemplateVariables(NativeWebRequest request) {
107 Map<String, String> variables = (Map<String, String>) request.getAttribute(
108 HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
109 return (variables != null ? variables : Collections.<String, String>emptyMap());
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,
126 MethodParameter methodParam, WebDataBinderFactory binderFactory, NativeWebRequest request)
127 throws Exception {
128
129 DataBinder binder = binderFactory.createBinder(request, null, attributeName);
130 ConversionService conversionService = binder.getConversionService();
131 if (conversionService != null) {
132 TypeDescriptor source = TypeDescriptor.valueOf(String.class);
133 TypeDescriptor target = new TypeDescriptor(methodParam);
134 if (conversionService.canConvert(source, target)) {
135 return binder.convertIfNecessary(sourceValue, methodParam.getParameterType(), methodParam);
136 }
137 }
138 return null;
139 }
140
141
142
143
144
145
146 @Override
147 protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
148 ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
149 ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
150 servletBinder.bind(servletRequest);
151 }
152
153 }