提交 a1b7a314 编写于 作者: R Rossen Stoyanchev

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
上级 e860fa9a
/*
* 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();
}
}
/*
* 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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册