您可以使用 servlet 过滤器,而不是使用 web.xml 的错误页面。 servlet 过滤器可用于捕获所有异常,或仅捕获特定异常,例如 org.springframework.web.portlet.NoHandlerFoundException。 (这就是“找不到处理程序”异常的意思吗?)
过滤器看起来像这样:
package com.example;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.springframework.web.portlet.NoHandlerFoundException;
public class ErrorHandlingFilter implements Filter {
public void init(FilterConfig config) throws ServletException { }
public void destroy() { }
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
try {
chain.doFilter(request, response);
} catch (NoHandlerFoundException e) {
// Or you could catch Exception, Error, Throwable...
// You probably want to add exception logging code here.
// Putting the exception into request scope so it can be used by the error handling page
request.setAttribute("exception", e);
// You probably want to add exception logging code here.
request.getRequestDispatcher("/WEB-INF/view/servlet-exception.vm").forward(request, response);
}
}
}
然后,借助 Spring 的 DelegatingFilterProxy 在 web.xml 中进行设置:
<filter>
<filter-name>errorHandlingFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>errorHandlingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最后,在你的 spring 上下文 xml 中将过滤器变成一个 spring bean:
<bean id="errorHandlingFilter" class="com.example.ErrorHandlingFilter" />
您可能需要试验过滤器链中过滤器的顺序,以便失败的请求仍然通过您提到的其他过滤器。如果您遇到问题,一种变体是执行 HTTP 重定向而不是转发,如下所示:
try {
chain.doFilter(request, response);
} catch (NoHandlerFoundException e) {
request.getSession().setAttribute("exception", e);
response.sendRedirect("/servlet-exception.vm");
}
这将迫使浏览器将您的错误处理页面作为新的 http 请求来请求,这可能更容易确保它首先通过所有正确的过滤器。如果您需要原始异常对象,则可以将其放入会话而不是请求中。