4444import org .springframework .util .ObjectUtils ;
4545import org .springframework .util .ReflectionUtils ;
4646import org .springframework .web .bind .annotation .ExceptionHandler ;
47+ import org .springframework .web .bind .annotation .ResponseStatus ;
4748import org .springframework .web .bind .support .WebArgumentResolver ;
4849import org .springframework .web .context .request .NativeWebRequest ;
4950import org .springframework .web .context .request .ServletWebRequest ;
@@ -89,14 +90,14 @@ protected ModelAndView doResolveException(HttpServletRequest request,
8990 if (handler != null ) {
9091 Method handlerMethod = findBestExceptionHandlerMethod (handler , ex );
9192 if (handlerMethod != null ) {
92- NativeWebRequest webRequest = new ServletWebRequest (request , response );
93+ ServletWebRequest webRequest = new ServletWebRequest (request , response );
9394 try {
9495 Object [] args = resolveHandlerArguments (handlerMethod , handler , webRequest , ex );
9596 if (logger .isDebugEnabled ()) {
9697 logger .debug ("Invoking request handler method: " + handlerMethod );
9798 }
9899 Object retVal = doInvokeMethod (handlerMethod , handler , args );
99- return getModelAndView (retVal );
100+ return getModelAndView (handlerMethod , handler . getClass (), retVal , webRequest );
100101 }
101102 catch (Exception invocationEx ) {
102103 logger .error ("Invoking request method resulted in exception : " + handlerMethod , invocationEx );
@@ -109,7 +110,7 @@ protected ModelAndView doResolveException(HttpServletRequest request,
109110 /**
110111 * Finds the handler method that matches the thrown exception best.
111112 *
112- * @param handler the handler object
113+ * @param handler the handler object
113114 * @param thrownException the exception to be handled
114115 * @return the best matching method; or <code>null</code> if none is found
115116 */
@@ -171,7 +172,9 @@ protected List<Class<? extends Throwable>> getHandledExceptions(Method method) {
171172 return result ;
172173 }
173174
174- /** Returns the best matching method. Uses the {@link DepthComparator}. */
175+ /**
176+ * Returns the best matching method. Uses the {@link DepthComparator}.
177+ */
175178 private Method getBestMatchingMethod (Exception thrownException ,
176179 Map <Class <? extends Throwable >, Method > resolverMethods ) {
177180 if (!resolverMethods .isEmpty ()) {
@@ -186,7 +189,9 @@ private Method getBestMatchingMethod(Exception thrownException,
186189 }
187190 }
188191
189- /** Resolves the arguments for the given method. Delegates to {@link #resolveCommonArgument}. */
192+ /**
193+ * Resolves the arguments for the given method. Delegates to {@link #resolveCommonArgument}.
194+ */
190195 private Object [] resolveHandlerArguments (Method handlerMethod ,
191196 Object handler ,
192197 NativeWebRequest webRequest ,
@@ -221,7 +226,7 @@ private Object[] resolveHandlerArguments(Method handlerMethod,
221226 * then checking {@link #resolveStandardArgument}.
222227 *
223228 * @param methodParameter the method parameter
224- * @param webRequest the request
229+ * @param webRequest the request
225230 * @param thrownException the exception thrown
226231 * @return the argument value, or {@link WebArgumentResolver#UNRESOLVED}
227232 */
@@ -256,8 +261,8 @@ protected Object resolveCommonArgument(MethodParameter methodParameter,
256261 * request {@link InputStream}, request {@link Reader}, response {@link OutputStream}, response {@link Writer},
257262 * and the given {@code thrownException}.
258263 *
259- * @param parameterType the method parameter type
260- * @param webRequest the request
264+ * @param parameterType the method parameter type
265+ * @param webRequest the request
261266 * @param thrownException the exception thrown
262267 * @return the argument value, or {@link WebArgumentResolver#UNRESOLVED}
263268 */
@@ -319,7 +324,16 @@ private Object doInvokeMethod(Method method, Object target, Object[] args) throw
319324 }
320325
321326 @ SuppressWarnings ("unchecked" )
322- private ModelAndView getModelAndView (Object returnValue ) {
327+ private ModelAndView getModelAndView (Method handlerMethod ,
328+ Class handlerType ,
329+ Object returnValue ,
330+ ServletWebRequest webRequest ) throws Exception {
331+
332+ if (handlerMethod .isAnnotationPresent (ResponseStatus .class )) {
333+ ResponseStatus responseStatus = handlerMethod .getAnnotation (ResponseStatus .class );
334+ HttpServletResponse response = webRequest .getResponse ();
335+ response .setStatus (responseStatus .value ().value ());
336+ }
323337 if (returnValue instanceof ModelAndView ) {
324338 return (ModelAndView ) returnValue ;
325339 }
@@ -343,7 +357,9 @@ else if (returnValue == null) {
343357 }
344358 }
345359
346- /** Comparator capable of sorting exceptions based on their depth from the thrown exception type. */
360+ /**
361+ * Comparator capable of sorting exceptions based on their depth from the thrown exception type.
362+ */
347363 private static class DepthComparator implements Comparator <Class <? extends Throwable >> {
348364
349365 private final Class <? extends Throwable > handlerExceptionType ;
0 commit comments