Add BindException to DefaultHandlerExceptionResolver
Previously DefaultHandlerExceptionResolver did not handle BindException but after this change it does. A BindException is raised when an @ModelAttribute annotated argument is not followed by a BindingResult argument. Hence this is unlikely to affect browser rendering. For programmatic clients however this change ensures an unhandled BindException is at least turned into a 400 error. Issue: SPR-9310
This commit is contained in:
parent
e860fa9a8b
commit
a1b7a314c1
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -32,12 +32,15 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
|
|||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -65,6 +68,9 @@ import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMeth
|
|||
* @see #handleHttpMessageNotReadable
|
||||
* @see #handleHttpMessageNotWritable
|
||||
* @see #handleMethodArgumentNotValidException
|
||||
* @see #handleMissingServletRequestParameter
|
||||
* @see #handleMissingServletRequestPart
|
||||
* @see #handleBindException
|
||||
*/
|
||||
public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||
|
||||
|
@ -136,6 +142,9 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
|||
else if (ex instanceof MissingServletRequestPartException) {
|
||||
return handleMissingServletRequestPartException((MissingServletRequestPartException) ex, request, response, handler);
|
||||
}
|
||||
else if (ex instanceof BindException) {
|
||||
return handleBindException((BindException) ex, request, response, handler);
|
||||
}
|
||||
}
|
||||
catch (Exception handlerException) {
|
||||
logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
|
||||
|
@ -346,8 +355,8 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
|||
}
|
||||
|
||||
/**
|
||||
* Handle the case where an argument annotated with {@code @Valid} such as
|
||||
* an {@link RequestBody} or {@link RequestPart} argument fails validation.
|
||||
* Handle the case where an argument annotated with {@code @Valid} such as
|
||||
* an {@link RequestBody} or {@link RequestPart} argument fails validation.
|
||||
* An HTTP 400 error is sent back to the client.
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
|
@ -362,8 +371,8 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
|||
}
|
||||
|
||||
/**
|
||||
* Handle the case where an @{@link RequestPart}, a {@link MultipartFile},
|
||||
* or a {@code javax.servlet.http.Part} argument is required but missing.
|
||||
* Handle the case where an {@linkplain RequestPart @RequestPart}, a {@link MultipartFile},
|
||||
* or a {@code javax.servlet.http.Part} argument is required but is missing.
|
||||
* An HTTP 400 error is sent back to the client.
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
|
@ -377,4 +386,21 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
|||
return new ModelAndView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the case where an {@linkplain ModelAttribute @ModelAttribute} method
|
||||
* argument has binding or validation errors and is not followed by another
|
||||
* method argument of type {@link BindingResult}.
|
||||
* By default an HTTP 400 error is sent back to the client.
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
* @param handler the executed handler
|
||||
* @return an empty ModelAndView indicating the exception was handled
|
||||
* @throws IOException potentially thrown from response.sendError()
|
||||
*/
|
||||
protected ModelAndView handleBindException(BindException ex, HttpServletRequest request,
|
||||
HttpServletResponse response, Object handler) throws IOException {
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -33,6 +33,7 @@ import org.springframework.http.converter.HttpMessageNotWritableException;
|
|||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
|
@ -157,6 +158,15 @@ public class DefaultHandlerExceptionResolverTests {
|
|||
assertEquals("Invalid status code", 400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleBindException() throws Exception {
|
||||
BindException ex = new BindException(new Object(), "name");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
|
||||
assertEquals("Invalid status code", 400, response.getStatus());
|
||||
}
|
||||
|
||||
public void handle(String arg) {
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Changes in version 3.2 M2 (2012-08-xx)
|
|||
* add defaultCharset property to StringHttpMessageConverter
|
||||
* add @ExceptionResolver annotation to detect classes with @ExceptionHandler methods
|
||||
* move RSS/Atom message converter registration ahead of jackson/jaxb2
|
||||
* handle BindException in DefaultHandlerExceptionResolver
|
||||
|
||||
|
||||
Changes in version 3.2 M1 (2012-05-28)
|
||||
|
|
Loading…
Reference in New Issue