2828import org .springframework .core .MethodParameter ;
2929import org .springframework .core .annotation .AnnotatedElementUtils ;
3030import org .springframework .core .annotation .SynthesizingMethodParameter ;
31+ import org .springframework .http .HttpStatus ;
3132import org .springframework .util .Assert ;
3233import org .springframework .util .ClassUtils ;
34+ import org .springframework .web .bind .annotation .ResponseStatus ;
3335
3436/**
3537 * Encapsulates information about a handler method consisting of a
@@ -65,7 +67,11 @@ public class HandlerMethod {
6567
6668 private final MethodParameter [] parameters ;
6769
68- private final HandlerMethod resolvedFromHandlerMethod ;
70+ private HttpStatus responseStatus ;
71+
72+ private String responseStatusReason ;
73+
74+ private HandlerMethod resolvedFromHandlerMethod ;
6975
7076
7177 /**
@@ -80,7 +86,7 @@ public HandlerMethod(Object bean, Method method) {
8086 this .method = method ;
8187 this .bridgedMethod = BridgeMethodResolver .findBridgedMethod (method );
8288 this .parameters = initMethodParameters ();
83- this . resolvedFromHandlerMethod = null ;
89+ evaluateResponseStatus () ;
8490 }
8591
8692 /**
@@ -96,7 +102,7 @@ public HandlerMethod(Object bean, String methodName, Class<?>... parameterTypes)
96102 this .method = bean .getClass ().getMethod (methodName , parameterTypes );
97103 this .bridgedMethod = BridgeMethodResolver .findBridgedMethod (this .method );
98104 this .parameters = initMethodParameters ();
99- this . resolvedFromHandlerMethod = null ;
105+ evaluateResponseStatus () ;
100106 }
101107
102108 /**
@@ -114,7 +120,7 @@ public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) {
114120 this .method = method ;
115121 this .bridgedMethod = BridgeMethodResolver .findBridgedMethod (method );
116122 this .parameters = initMethodParameters ();
117- this . resolvedFromHandlerMethod = null ;
123+ evaluateResponseStatus () ;
118124 }
119125
120126 /**
@@ -128,6 +134,8 @@ protected HandlerMethod(HandlerMethod handlerMethod) {
128134 this .method = handlerMethod .method ;
129135 this .bridgedMethod = handlerMethod .bridgedMethod ;
130136 this .parameters = handlerMethod .parameters ;
137+ this .responseStatus = handlerMethod .responseStatus ;
138+ this .responseStatusReason = handlerMethod .responseStatusReason ;
131139 this .resolvedFromHandlerMethod = handlerMethod .resolvedFromHandlerMethod ;
132140 }
133141
@@ -143,6 +151,8 @@ private HandlerMethod(HandlerMethod handlerMethod, Object handler) {
143151 this .method = handlerMethod .method ;
144152 this .bridgedMethod = handlerMethod .bridgedMethod ;
145153 this .parameters = handlerMethod .parameters ;
154+ this .responseStatus = handlerMethod .responseStatus ;
155+ this .responseStatusReason = handlerMethod .responseStatusReason ;
146156 this .resolvedFromHandlerMethod = handlerMethod ;
147157 }
148158
@@ -158,15 +168,27 @@ private MethodParameter[] initMethodParameters() {
158168 return result ;
159169 }
160170
171+ private void evaluateResponseStatus () {
172+ ResponseStatus annotation = getMethodAnnotation (ResponseStatus .class );
173+ if (annotation == null ) {
174+ annotation = AnnotatedElementUtils .findMergedAnnotation (getBeanType (), ResponseStatus .class );
175+ }
176+ if (annotation != null ) {
177+ this .responseStatus = annotation .code ();
178+ this .responseStatusReason = annotation .reason ();
179+ }
180+ }
181+
182+
161183 /**
162- * Returns the bean for this handler method.
184+ * Return the bean for this handler method.
163185 */
164186 public Object getBean () {
165187 return this .bean ;
166188 }
167189
168190 /**
169- * Returns the method for this handler method.
191+ * Return the method for this handler method.
170192 */
171193 public Method getMethod () {
172194 return this .method ;
@@ -190,18 +212,28 @@ protected Method getBridgedMethod() {
190212 }
191213
192214 /**
193- * Returns the method parameters for this handler method.
215+ * Return the method parameters for this handler method.
194216 */
195217 public MethodParameter [] getMethodParameters () {
196218 return this .parameters ;
197219 }
198220
199221 /**
200- * Return the HandlerMethod from which this HandlerMethod instance was
201- * resolved via {@link #createWithResolvedBean()}.
222+ * Return the specified response status, if any.
223+ * @since 4.3.8
224+ * @see ResponseStatus#code()
202225 */
203- public HandlerMethod getResolvedFromHandlerMethod () {
204- return this .resolvedFromHandlerMethod ;
226+ protected HttpStatus getResponseStatus () {
227+ return this .responseStatus ;
228+ }
229+
230+ /**
231+ * Return the associated response status reason, if any.
232+ * @since 4.3.8
233+ * @see ResponseStatus#reason()
234+ */
235+ protected String getResponseStatusReason () {
236+ return this .responseStatusReason ;
205237 }
206238
207239 /**
@@ -219,14 +251,14 @@ public MethodParameter getReturnValueType(Object returnValue) {
219251 }
220252
221253 /**
222- * Returns {@code true} if the method return type is void, {@code false} otherwise.
254+ * Return {@code true} if the method return type is void, {@code false} otherwise.
223255 */
224256 public boolean isVoid () {
225257 return Void .TYPE .equals (getReturnType ().getParameterType ());
226258 }
227259
228260 /**
229- * Returns a single annotation on the underlying method traversing its super methods
261+ * Return a single annotation on the underlying method traversing its super methods
230262 * if no annotation can be found on the given method itself.
231263 * <p>Also supports <em>merged</em> composed annotations with attribute
232264 * overrides as of Spring Framework 4.2.2.
@@ -248,6 +280,14 @@ public <A extends Annotation> boolean hasMethodAnnotation(Class<A> annotationTyp
248280 return AnnotatedElementUtils .hasAnnotation (this .method , annotationType );
249281 }
250282
283+ /**
284+ * Return the HandlerMethod from which this HandlerMethod instance was
285+ * resolved via {@link #createWithResolvedBean()}.
286+ */
287+ public HandlerMethod getResolvedFromHandlerMethod () {
288+ return this .resolvedFromHandlerMethod ;
289+ }
290+
251291 /**
252292 * If the provided instance contains a bean name rather than an object instance,
253293 * the bean name is resolved before a {@link HandlerMethod} is created and returned.
0 commit comments