@ComposedResponseStatus(responseStatus = HttpStatus.BAD_REQUEST) @SuppressWarnings("serial") private static class StatusCodeFromComposedResponseStatusException extends Exception { }
@Test public void statusCode() { StatusCodeException ex = new StatusCodeException(); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertResolved(mav, 400, null); }
@Test public void statusCodeFromComposedResponseStatus() { StatusCodeFromComposedResponseStatusException ex = new StatusCodeFromComposedResponseStatusException(); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertResolved(mav, 400, null); }
@Override @Nullable protected ModelAndView doResolveException( HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) { try { if (ex instanceof ResponseStatusException) { return resolveResponseStatusException((ResponseStatusException) ex, request, response, handler); } ResponseStatus status = AnnotatedElementUtils.findMergedAnnotation(ex.getClass(), ResponseStatus.class); if (status != null) { return resolveResponseStatus(status, request, response, handler, ex); } if (ex.getCause() instanceof Exception) { return doResolveException(request, response, handler, (Exception) ex.getCause()); } } catch (Exception resolveEx) { if (logger.isWarnEnabled()) { logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", resolveEx); } } return null; }
@Override public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { exceptionResolvers.add(0, new ResponseStatusExceptionResolver()); }
@Test public void statusCodeAndReasonMessage() { Locale locale = Locale.CHINESE; LocaleContextHolder.setLocale(locale); try { StaticMessageSource messageSource = new StaticMessageSource(); messageSource.addMessage("gone.reason", locale, "Gone reason message"); exceptionResolver.setMessageSource(messageSource); StatusCodeAndReasonMessageException ex = new StatusCodeAndReasonMessageException(); exceptionResolver.resolveException(request, response, null, ex); assertEquals("Invalid status reason", "Gone reason message", response.getErrorMessage()); } finally { LocaleContextHolder.resetLocaleContext(); } }
@Test public void statusCodeAndReason() { StatusCodeAndReasonException ex = new StatusCodeAndReasonException(); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertResolved(mav, 410, "You suck!"); }
@Test // SPR-12903 public void nestedException() throws Exception { Exception cause = new StatusCodeAndReasonMessageException(); TypeMismatchException ex = new TypeMismatchException("value", ITestBean.class, cause); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertResolved(mav, 410, "gone.reason"); }
@Test // SPR-15524 public void responseStatusExceptionWithReason() throws Exception { ResponseStatusException ex = new ResponseStatusException(HttpStatus.BAD_REQUEST, "The reason"); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertResolved(mav, 400, "The reason"); }
/** * Template method that handles an {@link ResponseStatusException}. * <p>The default implementation delegates to {@link #applyStatusAndReason} * with the status code and reason from the exception. * @param ex the exception * @param request current HTTP request * @param response current HTTP response * @param handler the executed handler, or {@code null} if none chosen at the * time of the exception, e.g. if multipart resolution failed * @return an empty ModelAndView, i.e. exception resolved * @since 5.0 */ protected ModelAndView resolveResponseStatusException(ResponseStatusException ex, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws Exception { int statusCode = ex.getStatus().value(); String reason = ex.getReason(); return applyStatusAndReason(statusCode, reason, response); }
@Test public void typeAndMethodLevel() throws Exception { initServlet(TypeAndMethodLevelImpl.class); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/bookings"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.service(request, response); assertEquals("doIt", response.getContentAsString()); }
@Test public void typeAndMethodLevel() throws Exception { initServlet(TypeAndMethodLevelImpl.class); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/bookings"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.service(request, response); assertEquals("doIt", response.getContentAsString()); }
@Test public void notAnnotated() { Exception ex = new Exception(); exceptionResolver.resolveException(request, response, null, ex); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertNull("ModelAndView returned", mav); }
@Before public void setup() { exceptionResolver.setWarnLogCategory(exceptionResolver.getClass().getName()); }
@Test public void responseStatusException() throws Exception { ResponseStatusException ex = new ResponseStatusException(HttpStatus.BAD_REQUEST); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertResolved(mav, 400, null); }
/** * Template method that handles the {@link ResponseStatus @ResponseStatus} annotation. * <p>The default implementation delegates to {@link #applyStatusAndReason} * with the status code and reason from the annotation. * @param responseStatus the {@code @ResponseStatus} annotation * @param request current HTTP request * @param response current HTTP response * @param handler the executed handler, or {@code null} if none chosen at the * time of the exception, e.g. if multipart resolution failed * @param ex the exception * @return an empty ModelAndView, i.e. exception resolved */ protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) throws Exception { int statusCode = responseStatus.code().value(); String reason = responseStatus.reason(); return applyStatusAndReason(statusCode, reason, response); }
@Test public void methodLevel() throws Exception { initServlet(MethodLevelImpl.class); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.service(request, response); assertEquals("doIt", response.getContentAsString()); }
@Test public void typeLevel() throws Exception { initServlet(TypeLevelImpl.class); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.service(request, response); assertEquals("doIt", response.getContentAsString()); }
@Test public void typeLevel() throws Exception { initServlet(TypeLevelImpl.class); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.service(request, response); assertEquals("doIt", response.getContentAsString()); }
@Test public void methodLevel() throws Exception { initServlet(MethodLevelImpl.class); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.service(request, response); assertEquals("doIt", response.getContentAsString()); }