Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@860 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
9 changed files with 1096 additions and 782 deletions
@ -0,0 +1,190 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.web.servlet.handler; |
||||||
|
|
||||||
|
import java.util.Set; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
|
||||||
|
import org.apache.commons.logging.Log; |
||||||
|
import org.apache.commons.logging.LogFactory; |
||||||
|
|
||||||
|
import org.springframework.core.Ordered; |
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver; |
||||||
|
import org.springframework.web.servlet.ModelAndView; |
||||||
|
|
||||||
|
/** |
||||||
|
* Abstract base class for {@link HandlerExceptionResolver} implementations. <p>Provides a set of mapped handlers that |
||||||
|
* the resolver should map to, and the {@link Ordered} implementation. |
||||||
|
* |
||||||
|
* @author Arjen Poutsma |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered { |
||||||
|
|
||||||
|
/** Logger available to subclasses */ |
||||||
|
protected final Log logger = LogFactory.getLog(getClass()); |
||||||
|
|
||||||
|
private int order = Ordered.LOWEST_PRECEDENCE; |
||||||
|
|
||||||
|
private Set mappedHandlers; |
||||||
|
|
||||||
|
private Class[] mappedHandlerClasses; |
||||||
|
|
||||||
|
private Log warnLogger; |
||||||
|
|
||||||
|
public void setOrder(int order) { |
||||||
|
this.order = order; |
||||||
|
} |
||||||
|
|
||||||
|
public int getOrder() { |
||||||
|
return this.order; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Specify the set of handlers that this exception resolver should apply to. The exception mappings and the default |
||||||
|
* error view will only apply to the specified handlers. <p>If no handlers and handler classes are set, the exception |
||||||
|
* mappings and the default error view will apply to all handlers. This means that a specified default error view will |
||||||
|
* be used as fallback for all exceptions; any further HandlerExceptionResolvers in the chain will be ignored in this |
||||||
|
* case. |
||||||
|
*/ |
||||||
|
public void setMappedHandlers(Set mappedHandlers) { |
||||||
|
this.mappedHandlers = mappedHandlers; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Specify the set of classes that this exception resolver should apply to. The exception mappings and the default |
||||||
|
* error view will only apply to handlers of the specified type; the specified types may be interfaces and superclasses |
||||||
|
* of handlers as well. <p>If no handlers and handler classes are set, the exception mappings and the default error |
||||||
|
* view will apply to all handlers. This means that a specified default error view will be used as fallback for all |
||||||
|
* exceptions; any further HandlerExceptionResolvers in the chain will be ignored in this case. |
||||||
|
*/ |
||||||
|
public void setMappedHandlerClasses(Class[] mappedHandlerClasses) { |
||||||
|
this.mappedHandlerClasses = mappedHandlerClasses; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the log category for warn logging. The name will be passed to the underlying logger implementation through |
||||||
|
* Commons Logging, getting interpreted as log category according to the logger's configuration. <p>Default is no warn |
||||||
|
* logging. Specify this setting to activate warn logging into a specific category. Alternatively, override the {@link |
||||||
|
* #logException} method for custom logging. |
||||||
|
* |
||||||
|
* @see org.apache.commons.logging.LogFactory#getLog(String) |
||||||
|
* @see org.apache.log4j.Logger#getLogger(String) |
||||||
|
* @see java.util.logging.Logger#getLogger(String) |
||||||
|
*/ |
||||||
|
public void setWarnLogCategory(String loggerName) { |
||||||
|
this.warnLogger = LogFactory.getLog(loggerName); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Checks whether this resolver is supposed to apply (i.e. the handler matches in case of "mappedHandlers" having been |
||||||
|
* specified), then delegates to the {@link #doResolveException} template method. |
||||||
|
*/ |
||||||
|
public ModelAndView resolveException(HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler, |
||||||
|
Exception ex) { |
||||||
|
|
||||||
|
if (shouldApplyTo(request, handler)) { |
||||||
|
// Log exception, both at debug log level and at warn level, if desired.
|
||||||
|
if (logger.isDebugEnabled()) { |
||||||
|
logger.debug("Resolving exception from handler [" + handler + "]: " + ex); |
||||||
|
} |
||||||
|
logException(ex, request); |
||||||
|
return doResolveException(request, response, handler, ex); |
||||||
|
} |
||||||
|
else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Check whether this resolver is supposed to apply to the given handler. <p>The default implementation checks against |
||||||
|
* the specified mapped handlers and handler classes, if any. |
||||||
|
* |
||||||
|
* @param request current HTTP request |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return whether this resolved should proceed with resolving the exception for the given request and handler |
||||||
|
* @see #setMappedHandlers |
||||||
|
* @see #setMappedHandlerClasses |
||||||
|
*/ |
||||||
|
protected boolean shouldApplyTo(HttpServletRequest request, Object handler) { |
||||||
|
if (handler != null) { |
||||||
|
if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (this.mappedHandlerClasses != null) { |
||||||
|
for (Class handlerClass : this.mappedHandlerClasses) { |
||||||
|
if (handlerClass.isInstance(handler)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// Else only apply if there are no explicit handler mappings.
|
||||||
|
return (this.mappedHandlers == null && this.mappedHandlerClasses == null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Log the given exception at warn level, provided that warn logging has been activated through the {@link |
||||||
|
* #setWarnLogCategory "warnLogCategory"} property. <p>Calls {@link #buildLogMessage} in order to determine the |
||||||
|
* concrete message to log. Always passes the full exception to the logger. |
||||||
|
* |
||||||
|
* @param ex the exception that got thrown during handler execution |
||||||
|
* @param request current HTTP request (useful for obtaining metadata) |
||||||
|
* @see #setWarnLogCategory |
||||||
|
* @see #buildLogMessage |
||||||
|
* @see org.apache.commons.logging.Log#warn(Object, Throwable) |
||||||
|
*/ |
||||||
|
protected void logException(Exception ex, HttpServletRequest request) { |
||||||
|
if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) { |
||||||
|
this.warnLogger.warn(buildLogMessage(ex, request), ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a log message for the given exception, occured during processing the given request. |
||||||
|
* |
||||||
|
* @param ex the exception that got thrown during handler execution |
||||||
|
* @param request current HTTP request (useful for obtaining metadata) |
||||||
|
* @return the log message to use |
||||||
|
*/ |
||||||
|
protected String buildLogMessage(Exception ex, HttpServletRequest request) { |
||||||
|
return "Handler execution resulted in exception"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Actually resolve the given exception that got thrown during on handler execution, returning a ModelAndView that |
||||||
|
* represents a specific error page if appropriate. <p>May be overridden in subclasses, in order to apply specific |
||||||
|
* exception checks. Note that this template method will be invoked <i>after</i> checking whether this resolved applies |
||||||
|
* ("mappedHandlers" etc), so an implementation may simply proceed with its actual exception handling. |
||||||
|
* |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @param ex the exception that got thrown during handler execution |
||||||
|
* @return a corresponding ModelAndView to forward to, or <code>null</code> for default processing |
||||||
|
*/ |
||||||
|
protected abstract ModelAndView doResolveException(HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler, |
||||||
|
Exception ex); |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,280 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.web.servlet.handler; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
|
||||||
|
import org.apache.commons.logging.Log; |
||||||
|
import org.apache.commons.logging.LogFactory; |
||||||
|
|
||||||
|
import org.springframework.beans.TypeMismatchException; |
||||||
|
import org.springframework.core.Ordered; |
||||||
|
import org.springframework.http.MediaType; |
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException; |
||||||
|
import org.springframework.http.converter.HttpMessageNotWritableException; |
||||||
|
import org.springframework.util.StringUtils; |
||||||
|
import org.springframework.web.HttpMediaTypeNotSupportedException; |
||||||
|
import org.springframework.web.HttpRequestMethodNotSupportedException; |
||||||
|
import org.springframework.web.bind.MissingServletRequestParameterException; |
||||||
|
import org.springframework.web.servlet.ModelAndView; |
||||||
|
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default implementation of the {@link org.springframework.web.servlet.HandlerExceptionResolver |
||||||
|
* HandlerExceptionResolver} interface that resolves standard Spring exceptions. <p>Default implementations typically |
||||||
|
* set the response status. |
||||||
|
* |
||||||
|
* @author Arjen Poutsma |
||||||
|
* @see #handleNoSuchRequestHandlingMethod |
||||||
|
* @see #handleHttpRequestMethodNotSupported |
||||||
|
* @see #handleHttpMediaTypeNotSupported |
||||||
|
* @see #handleMissingServletRequestParameter |
||||||
|
* @see #handleTypeMismatch |
||||||
|
* @see #handleHttpMessageNotReadable |
||||||
|
* @see #handleHttpMessageNotWritable |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver { |
||||||
|
|
||||||
|
/** |
||||||
|
* Log category to use when no mapped handler is found for a request. |
||||||
|
* |
||||||
|
* @see #pageNotFoundLogger |
||||||
|
*/ |
||||||
|
public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound"; |
||||||
|
|
||||||
|
/** |
||||||
|
* Additional logger to use when no mapped handler is found for a request. |
||||||
|
* |
||||||
|
* @see #PAGE_NOT_FOUND_LOG_CATEGORY |
||||||
|
*/ |
||||||
|
protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY); |
||||||
|
|
||||||
|
/** Sets the {@linkplain #setOrder(int) order} to {@link #LOWEST_PRECEDENCE}. */ |
||||||
|
public DefaultHandlerExceptionResolver() { |
||||||
|
setOrder(Ordered.LOWEST_PRECEDENCE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected ModelAndView doResolveException(HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler, |
||||||
|
Exception ex) { |
||||||
|
try { |
||||||
|
if (ex instanceof NoSuchRequestHandlingMethodException) { |
||||||
|
return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response, |
||||||
|
handler); |
||||||
|
} |
||||||
|
else if (ex instanceof HttpRequestMethodNotSupportedException) { |
||||||
|
return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request, |
||||||
|
response, handler); |
||||||
|
} |
||||||
|
else if (ex instanceof HttpMediaTypeNotSupportedException) { |
||||||
|
return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response, |
||||||
|
handler); |
||||||
|
} |
||||||
|
else if (ex instanceof MissingServletRequestParameterException) { |
||||||
|
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request, |
||||||
|
response, handler); |
||||||
|
} |
||||||
|
else if (ex instanceof TypeMismatchException) { |
||||||
|
return handleTypeMismatch((TypeMismatchException) ex, request, response, handler); |
||||||
|
} |
||||||
|
else if (ex instanceof HttpMessageNotReadableException) { |
||||||
|
return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, request, response, handler); |
||||||
|
} |
||||||
|
else if (ex instanceof HttpMessageNotWritableException) { |
||||||
|
return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, request, response, handler); |
||||||
|
} |
||||||
|
} |
||||||
|
catch (Exception handlerException) { |
||||||
|
logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case where no request handler method was found. <p>The default implementation logs a warning, sends an |
||||||
|
* HTTP 404 error, and returns an empty {@code ModelAndView}. Alternatively, a fallback view could be chosen, or the |
||||||
|
* NoSuchRequestHandlingMethodException could be rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the NoSuchRequestHandlingMethodException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
pageNotFoundLogger.warn(ex.getMessage()); |
||||||
|
response.sendError(HttpServletResponse.SC_NOT_FOUND); |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case where no request handler method was found for the particular HTTP request method. <p>The default |
||||||
|
* implementation logs a warning, sends an HTTP 405 error, sets the "Allow" header, and returns an empty {@code |
||||||
|
* ModelAndView}. Alternatively, a fallback view could be chosen, or the HttpRequestMethodNotSupportedException could |
||||||
|
* be rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the HttpRequestMethodNotSupportedException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
pageNotFoundLogger.warn(ex.getMessage()); |
||||||
|
String[] supportedMethods = ex.getSupportedMethods(); |
||||||
|
if (supportedMethods != null) { |
||||||
|
response.setHeader("Allow", StringUtils.arrayToDelimitedString(supportedMethods, ", ")); |
||||||
|
} |
||||||
|
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ex.getMessage()); |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case where no {@linkplain org.springframework.http.converter.HttpMessageConverter message converters} |
||||||
|
* were found for the PUT or POSTed content. <p>The default implementation sends an HTTP 415 error, sets the "Allow" |
||||||
|
* header, and returns an empty {@code ModelAndView}. Alternatively, a fallback view could be chosen, or the |
||||||
|
* HttpMediaTypeNotSupportedException could be rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the HttpMediaTypeNotSupportedException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE); |
||||||
|
List<MediaType> mediaTypes = ex.getSupportedMediaTypes(); |
||||||
|
if (mediaTypes != null) { |
||||||
|
response.setHeader("Accept", MediaType.toString(mediaTypes)); |
||||||
|
} |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case when a required parameter is missing. <p>The default implementation sends an HTTP 400 error, and |
||||||
|
* returns an empty {@code ModelAndView}. Alternatively, a fallback view could be chosen, or the |
||||||
|
* MissingServletRequestParameterException could be rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the MissingServletRequestParameterException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleMissingServletRequestParameter(MissingServletRequestParameterException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
response.sendError(HttpServletResponse.SC_BAD_REQUEST); |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case when a {@link org.springframework.web.bind.WebDataBinder} conversion error occurs. <p>The default |
||||||
|
* implementation sends an HTTP 400 error, and returns an empty {@code ModelAndView}. Alternatively, a fallback view |
||||||
|
* could be chosen, or the TypeMismatchException could be rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the TypeMismatchException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleTypeMismatch(TypeMismatchException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
response.sendError(HttpServletResponse.SC_BAD_REQUEST); |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case where a {@linkplain org.springframework.http.converter.HttpMessageConverter message converter} can |
||||||
|
* not read from a HTTP request. <p>The default implementation sends an HTTP 400 error, and returns an empty {@code |
||||||
|
* ModelAndView}. Alternatively, a fallback view could be chosen, or the HttpMediaTypeNotSupportedException could be |
||||||
|
* rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the HttpMessageNotReadableException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleHttpMessageNotReadable(HttpMessageNotReadableException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
response.sendError(HttpServletResponse.SC_BAD_REQUEST); |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle the case where a {@linkplain org.springframework.http.converter.HttpMessageConverter message converter} can |
||||||
|
* not write to a HTTP request. <p>The default implementation sends an HTTP 500 error, and returns an empty {@code |
||||||
|
* ModelAndView}. Alternatively, a fallback view could be chosen, or the HttpMediaTypeNotSupportedException could be |
||||||
|
* rethrown as-is. |
||||||
|
* |
||||||
|
* @param ex the HttpMessageNotWritableException to be handled |
||||||
|
* @param request current HTTP request |
||||||
|
* @param response current HTTP response |
||||||
|
* @param handler the executed handler, or <code>null</code> if none chosen at the time of the exception (for example, |
||||||
|
* if multipart resolution failed) |
||||||
|
* @return a ModelAndView to render, or <code>null</code> if handled directly |
||||||
|
* @throws Exception an Exception that should be thrown as result of the servlet request |
||||||
|
*/ |
||||||
|
protected ModelAndView handleHttpMessageNotWritable(HttpMessageNotWritableException ex, |
||||||
|
HttpServletRequest request, |
||||||
|
HttpServletResponse response, |
||||||
|
Object handler) throws Exception { |
||||||
|
|
||||||
|
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); |
||||||
|
return new ModelAndView(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,107 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.web.servlet.handler; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
|
||||||
|
import static org.junit.Assert.*; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import org.springframework.beans.TypeMismatchException; |
||||||
|
import org.springframework.http.MediaType; |
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException; |
||||||
|
import org.springframework.http.converter.HttpMessageNotWritableException; |
||||||
|
import org.springframework.mock.web.MockHttpServletRequest; |
||||||
|
import org.springframework.mock.web.MockHttpServletResponse; |
||||||
|
import org.springframework.web.HttpMediaTypeNotSupportedException; |
||||||
|
import org.springframework.web.HttpRequestMethodNotSupportedException; |
||||||
|
import org.springframework.web.bind.MissingServletRequestParameterException; |
||||||
|
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; |
||||||
|
|
||||||
|
/** @author Arjen Poutsma */ |
||||||
|
public class DefaultHandlerExceptionResolverTests { |
||||||
|
|
||||||
|
private DefaultHandlerExceptionResolver exceptionResolver; |
||||||
|
|
||||||
|
private MockHttpServletRequest request; |
||||||
|
|
||||||
|
private MockHttpServletResponse response; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
exceptionResolver = new DefaultHandlerExceptionResolver(); |
||||||
|
request = new MockHttpServletRequest(); |
||||||
|
response = new MockHttpServletResponse(); |
||||||
|
request.setMethod("GET"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleNoSuchRequestHandlingMethod() { |
||||||
|
NoSuchRequestHandlingMethodException ex = new NoSuchRequestHandlingMethodException(request); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 404, response.getStatus()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleHttpRequestMethodNotSupported() { |
||||||
|
HttpRequestMethodNotSupportedException ex = |
||||||
|
new HttpRequestMethodNotSupportedException("GET", new String[]{"POST", "PUT"}); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 405, response.getStatus()); |
||||||
|
assertEquals("Invalid Allow header", "POST, PUT", response.getHeader("Allow")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleHttpMediaTypeNotSupported() { |
||||||
|
HttpMediaTypeNotSupportedException ex = new HttpMediaTypeNotSupportedException(new MediaType("text", "plain"), |
||||||
|
Collections.singletonList(new MediaType("application", "pdf"))); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 415, response.getStatus()); |
||||||
|
assertEquals("Invalid Accept header", "application/pdf", response.getHeader("Accept")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleMissingServletRequestParameter() { |
||||||
|
MissingServletRequestParameterException ex = new MissingServletRequestParameterException("foo", "bar"); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 400, response.getStatus()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleTypeMismatch() { |
||||||
|
TypeMismatchException ex = new TypeMismatchException("foo", String.class); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 400, response.getStatus()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleHttpMessageNotReadable() { |
||||||
|
HttpMessageNotReadableException ex = new HttpMessageNotReadableException("foo"); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 400, response.getStatus()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void handleHttpMessageNotWritable() { |
||||||
|
HttpMessageNotWritableException ex = new HttpMessageNotWritableException("foo"); |
||||||
|
exceptionResolver.resolveException(request, response, null, ex); |
||||||
|
assertEquals("Invalid status code", 500, response.getStatus()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue