diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java index 91380bf5cd2..2d82548f3eb 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java @@ -64,7 +64,7 @@ public class HandlerMethod { private final MethodParameter[] parameters; - private final HandlerMethod resolvedFromHandlerMethod; + private HandlerMethod resolvedFromHandlerMethod; /** @@ -79,7 +79,6 @@ public class HandlerMethod { this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); - this.resolvedFromHandlerMethod = null; } /** @@ -95,7 +94,6 @@ public class HandlerMethod { this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); this.parameters = initMethodParameters(); - this.resolvedFromHandlerMethod = null; } /** @@ -113,7 +111,6 @@ public class HandlerMethod { this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); - this.resolvedFromHandlerMethod = null; } /** @@ -158,14 +155,14 @@ public class HandlerMethod { } /** - * Returns the bean for this handler method. + * Return the bean for this handler method. */ public Object getBean() { return this.bean; } /** - * Returns the method for this handler method. + * Return the method for this handler method. */ public Method getMethod() { return this.method; @@ -189,21 +186,12 @@ public class HandlerMethod { } /** - * Returns the method parameters for this handler method. + * Return the method parameters for this handler method. */ public MethodParameter[] getMethodParameters() { return this.parameters; } - /** - * Return the HandlerMethod from which this HandlerMethod instance was - * resolved via {@link #createWithResolvedBean()}. - * @since 4.3 - */ - public HandlerMethod getResolvedFromHandlerMethod() { - return this.resolvedFromHandlerMethod; - } - /** * Return the HandlerMethod return type. */ @@ -219,14 +207,14 @@ public class HandlerMethod { } /** - * Returns {@code true} if the method return type is void, {@code false} otherwise. + * Return {@code true} if the method return type is void, {@code false} otherwise. */ public boolean isVoid() { return Void.TYPE.equals(getReturnType().getParameterType()); } /** - * Returns a single annotation on the underlying method traversing its super methods + * Return a single annotation on the underlying method traversing its super methods * if no annotation can be found on the given method itself. *
Also supports merged composed annotations with attribute * overrides as of Spring Framework 4.3. @@ -248,6 +236,15 @@ public class HandlerMethod { return AnnotatedElementUtils.hasAnnotation(this.method, annotationType); } + /** + * Return the HandlerMethod from which this HandlerMethod instance was + * resolved via {@link #createWithResolvedBean()}. + * @since 4.3 + */ + public HandlerMethod getResolvedFromHandlerMethod() { + return this.resolvedFromHandlerMethod; + } + /** * If the provided instance contains a bean name rather than an object instance, * the bean name is resolved before a {@link HandlerMethod} is created and returned. diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 675675bdc88..44b89ccb199 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -28,8 +28,10 @@ import org.springframework.core.GenericTypeResolver; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.SynthesizingMethodParameter; +import org.springframework.http.HttpStatus; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.web.bind.annotation.ResponseStatus; /** * Encapsulates information about a handler method consisting of a @@ -65,7 +67,11 @@ public class HandlerMethod { private final MethodParameter[] parameters; - private final HandlerMethod resolvedFromHandlerMethod; + private HttpStatus responseStatus; + + private String responseStatusReason; + + private HandlerMethod resolvedFromHandlerMethod; /** @@ -80,7 +86,7 @@ public class HandlerMethod { this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); - this.resolvedFromHandlerMethod = null; + evaluateResponseStatus(); } /** @@ -96,7 +102,7 @@ public class HandlerMethod { this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); this.parameters = initMethodParameters(); - this.resolvedFromHandlerMethod = null; + evaluateResponseStatus(); } /** @@ -114,7 +120,7 @@ public class HandlerMethod { this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); - this.resolvedFromHandlerMethod = null; + evaluateResponseStatus(); } /** @@ -128,6 +134,8 @@ public class HandlerMethod { this.method = handlerMethod.method; this.bridgedMethod = handlerMethod.bridgedMethod; this.parameters = handlerMethod.parameters; + this.responseStatus = handlerMethod.responseStatus; + this.responseStatusReason = handlerMethod.responseStatusReason; this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod; } @@ -143,6 +151,8 @@ public class HandlerMethod { this.method = handlerMethod.method; this.bridgedMethod = handlerMethod.bridgedMethod; this.parameters = handlerMethod.parameters; + this.responseStatus = handlerMethod.responseStatus; + this.responseStatusReason = handlerMethod.responseStatusReason; this.resolvedFromHandlerMethod = handlerMethod; } @@ -158,15 +168,27 @@ public class HandlerMethod { return result; } + private void evaluateResponseStatus() { + ResponseStatus annotation = getMethodAnnotation(ResponseStatus.class); + if (annotation == null) { + annotation = AnnotatedElementUtils.findMergedAnnotation(getBeanType(), ResponseStatus.class); + } + if (annotation != null) { + this.responseStatus = annotation.code(); + this.responseStatusReason = annotation.reason(); + } + } + + /** - * Returns the bean for this handler method. + * Return the bean for this handler method. */ public Object getBean() { return this.bean; } /** - * Returns the method for this handler method. + * Return the method for this handler method. */ public Method getMethod() { return this.method; @@ -190,18 +212,28 @@ public class HandlerMethod { } /** - * Returns the method parameters for this handler method. + * Return the method parameters for this handler method. */ public MethodParameter[] getMethodParameters() { return this.parameters; } /** - * Return the HandlerMethod from which this HandlerMethod instance was - * resolved via {@link #createWithResolvedBean()}. + * Return the specified response status, if any. + * @since 4.3.8 + * @see ResponseStatus#code() */ - public HandlerMethod getResolvedFromHandlerMethod() { - return this.resolvedFromHandlerMethod; + protected HttpStatus getResponseStatus() { + return this.responseStatus; + } + + /** + * Return the associated response status reason, if any. + * @since 4.3.8 + * @see ResponseStatus#reason() + */ + protected String getResponseStatusReason() { + return this.responseStatusReason; } /** @@ -219,14 +251,14 @@ public class HandlerMethod { } /** - * Returns {@code true} if the method return type is void, {@code false} otherwise. + * Return {@code true} if the method return type is void, {@code false} otherwise. */ public boolean isVoid() { return Void.TYPE.equals(getReturnType().getParameterType()); } /** - * Returns a single annotation on the underlying method traversing its super methods + * Return a single annotation on the underlying method traversing its super methods * if no annotation can be found on the given method itself. *
Also supports merged composed annotations with attribute * overrides as of Spring Framework 4.2.2. @@ -248,6 +280,14 @@ public class HandlerMethod { return AnnotatedElementUtils.hasAnnotation(this.method, annotationType); } + /** + * Return the HandlerMethod from which this HandlerMethod instance was + * resolved via {@link #createWithResolvedBean()}. + */ + public HandlerMethod getResolvedFromHandlerMethod() { + return this.resolvedFromHandlerMethod; + } + /** * If the provided instance contains a bean name rather than an object instance, * the bean name is resolved before a {@link HandlerMethod} is created and returned. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java index d1f7a1e0096..ec62b4c4d34 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java @@ -24,7 +24,6 @@ import java.util.concurrent.Callable; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; -import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.http.HttpStatus; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -58,11 +57,6 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { private static final Method CALLABLE_METHOD = ClassUtils.getMethod(Callable.class, "call"); - - private HttpStatus responseStatus; - - private String responseReason; - private HandlerMethodReturnValueHandlerComposite returnValueHandlers; @@ -71,7 +65,6 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { */ public ServletInvocableHandlerMethod(Object handler, Method method) { super(handler, method); - initResponseStatus(); } /** @@ -79,21 +72,9 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { */ public ServletInvocableHandlerMethod(HandlerMethod handlerMethod) { super(handlerMethod); - initResponseStatus(); } - private void initResponseStatus() { - ResponseStatus annotation = getMethodAnnotation(ResponseStatus.class); - if (annotation == null) { - annotation = AnnotatedElementUtils.findMergedAnnotation(getBeanType(), ResponseStatus.class); - } - if (annotation != null) { - this.responseStatus = annotation.code(); - this.responseReason = annotation.reason(); - } - } - /** * Register {@link HandlerMethodReturnValueHandler} instances to use to * handle return values. @@ -117,12 +98,12 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { setResponseStatus(webRequest); if (returnValue == null) { - if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) { + if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) { mavContainer.setRequestHandled(true); return; } } - else if (StringUtils.hasText(this.responseReason)) { + else if (StringUtils.hasText(getResponseStatusReason())) { mavContainer.setRequestHandled(true); return; } @@ -144,17 +125,21 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { * Set the response status according to the {@link ResponseStatus} annotation. */ private void setResponseStatus(ServletWebRequest webRequest) throws IOException { - if (this.responseStatus == null) { + HttpStatus status = getResponseStatus(); + if (status == null) { return; } - if (StringUtils.hasText(this.responseReason)) { - webRequest.getResponse().sendError(this.responseStatus.value(), this.responseReason); + + String reason = getResponseStatusReason(); + if (StringUtils.hasText(reason)) { + webRequest.getResponse().sendError(status.value(), reason); } else { - webRequest.getResponse().setStatus(this.responseStatus.value()); + webRequest.getResponse().setStatus(status.value()); } + // To be picked up by RedirectView - webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, this.responseStatus); + webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, status); } /** @@ -166,13 +151,6 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { return webRequest.isNotModified(); } - /** - * Does this method have the response status instruction? - */ - private boolean hasResponseStatus() { - return (this.responseStatus != null); - } - private String getReturnValueHandlingErrorMessage(String message, Object returnValue) { StringBuilder sb = new StringBuilder(message); if (returnValue != null) {