diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
index 4c0870cc48..4baff7978b 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
@@ -45,6 +45,7 @@ import org.springframework.context.i18n.LocaleContext;
import org.springframework.core.OrderComparator;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
+import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.ui.context.ThemeSource;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -277,6 +278,9 @@ public class DispatcherServlet extends FrameworkServlet {
/** Perform cleanup of request attributes after include request? */
private boolean cleanupAfterInclude = true;
+ /** Throw a NoHandlerFoundException if no Handler was found to process this request? **/
+ private boolean throwExceptionIfNoHandlerFound = false;
+
/** MultipartResolver used by this servlet */
private MultipartResolver multipartResolver;
@@ -408,6 +412,24 @@ public class DispatcherServlet extends FrameworkServlet {
this.detectAllViewResolvers = detectAllViewResolvers;
}
+ /**
+ * Set whether to throw a NoHandlerFoundException when no Handler was found for this request.
+ * This exception can then be caught with a HandlerExceptionResolver or an
+ * {@code @ExceptionHandler} controller method.
+ *
+ *
Note that if
+ * {@link org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler}
+ * is used, then requests will always be forwarded to the default servlet and
+ * a NoHandlerFoundException would never be thrown in that case.
+ *
+ *
Default is "false", meaning the DispatcherServlet sends a NOT_FOUND error
+ * through the Servlet response.
+ * @since 4.0
+ */
+ public void setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound) {
+ this.throwExceptionIfNoHandlerFound = throwExceptionIfNoHandlerFound;
+ }
+
/**
* Set whether to perform cleanup of request attributes after an include request, that is,
* whether to reset the original state of all request attributes after the DispatcherServlet
@@ -1097,7 +1119,13 @@ public class DispatcherServlet extends FrameworkServlet {
pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + requestUri +
"] in DispatcherServlet with name '" + getServletName() + "'");
}
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ if(throwExceptionIfNoHandlerFound) {
+ ServletServerHttpRequest req = new ServletServerHttpRequest(request);
+ throw new NoHandlerFoundException(req.getMethod().name(),
+ req.getServletRequest().getRequestURI(),req.getHeaders());
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
}
/**
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java
new file mode 100644
index 0000000000..5c8989b633
--- /dev/null
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/NoHandlerFoundException.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2002-2013 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;
+
+import javax.servlet.ServletException;
+
+import org.springframework.http.HttpHeaders;
+
+/**
+ * Exception to be thrown if DispatcherServlet is unable to determine
+ * a corresponding handler for an incoming HTTP request.
+ * The DispatcherServlet throws this exception only if its
+ * throwExceptionIfNoHandlerFound property is set to "true".
+ *
+ * @author Brian Clozel
+ * @since 4.0
+ * @see org.springframework.web.servlet.DispatcherServlet
+ */
+@SuppressWarnings("serial")
+public class NoHandlerFoundException extends ServletException {
+
+ private final String httpMethod;
+
+ private final String requestURL;
+
+ private final HttpHeaders headers;
+
+
+ /**
+ * Constructor for NoHandlerFoundException.
+ * @param httpMethod the HTTP method
+ * @param requestURL the HTTP request URL
+ * @param headers the HTTP request headers
+ */
+ public NoHandlerFoundException(String httpMethod, String requestURL, HttpHeaders headers) {
+ super("No handler found for " + httpMethod + " " + requestURL + ", headers=" + headers);
+ this.httpMethod = httpMethod;
+ this.requestURL = requestURL;
+ this.headers = headers;
+ }
+
+ public String getHttpMethod() {
+ return this.httpMethod;
+ }
+
+ public String getRequestURL() {
+ return this.requestURL;
+ }
+
+ public HttpHeaders getHeaders() {
+ return this.headers;
+ }
+
+}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java
index 8e00031dc2..9671767886 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -42,6 +42,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
+import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
/**
@@ -102,7 +103,8 @@ public abstract class ResponseEntityExceptionHandler {
HttpMessageNotWritableException.class,
MethodArgumentNotValidException.class,
MissingServletRequestPartException.class,
- BindException.class
+ BindException.class,
+ NoHandlerFoundException.class
})
public final ResponseEntity