将异常从servlet转发到jsp页面的好方法是什么?

将异常从servlet转发到jsp页面的好方法是什么?,jsp,exception,tomcat,servlets,Jsp,Exception,Tomcat,Servlets,我知道我可以像这样在web.xml中放一些东西 <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error.jsp</location> </error-page> java.lang.Throwable /error.jsp 然而,jsp页面不会显示任何有建设性的信息,因为它不会得到异常的

我知道我可以像这样在web.xml中放一些东西

<error-page>  
   <exception-type>java.lang.Throwable</exception-type>  
   <location>/error.jsp</location>  
</error-page>

java.lang.Throwable
/error.jsp
然而,jsp页面不会显示任何有建设性的信息,因为它不会得到异常的确切内容。我知道我们可以通过不同的
异常类型将不同的异常转发到不同的页面,但这太多了,无法在web.xml中编写。我希望一页就足够了,另一页就可以处理404这样的错误

那么,我应该如何将异常信息传递给jsp页面呢?使用会话


理想的情况可能是页面获取异常信息并显示一些相关消息,而不向用户显示异常。相反,它可以将其登录到一个文件中以供将来参考。实现这一目标的最佳方法是什么?谢谢。

是的,我认为会话是存储与当前请求相关的异常的好地方

不要忘记在处理完异常后清除它


此外,您还可以将一个错误代码(而不是异常)从支持代码传递到表示层,在表示层中,可以使用属性文件将其转换为某种意义上的用户完全错误。

有关异常的信息已由多个请求属性提供。您可以在中找到所有这些属性的名称:

  • 错误\u异常
    -
  • 错误\u异常\u类型
    -
  • 错误消息
    -
  • 错误\u请求\u URI
    -
  • 错误\u SERVLET\u名称
    -
  • 错误\u状态\u代码
    -
因此,简而言之,这个JSP示例应该显示所有可能的异常细节:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<ul>
    <li>Exception: <c:out value="${requestScope['javax.servlet.error.exception']}" /></li>
    <li>Exception type: <c:out value="${requestScope['javax.servlet.error.exception_type']}" /></li>
    <li>Exception message: <c:out value="${requestScope['javax.servlet.error.message']}" /></li>
    <li>Request URI: <c:out value="${requestScope['javax.servlet.error.request_uri']}" /></li>
    <li>Servlet name: <c:out value="${requestScope['javax.servlet.error.servlet_name']}" /></li>
    <li>Status code: <c:out value="${requestScope['javax.servlet.error.status_code']}" /></li>
</ul>
只有在使用EL 2.2或更新版本时,才能按如下方式打印其stacktrace:

注册在
/WEB-INF/functions.tld

<%@ taglib prefix="my" uri="http://example.com/functions" %>
...
<pre>${my:printStackTrace(exception)}</pre>

“清除异常”是什么意思?应用程序不是在引发未捕获的异常后终止吗?如果代码中没有出现未捕获的异常,这将起作用。这意味着您可以尝试/捕获所有可以生成异常的代码,然后将该异常存储在会话对象中。如果从代码中抛出未捕获的异常,那么我担心唯一的解决方案是在web XMLlet中声明错误页/错误代码。如果出现NullPointerException,服务器如何知道从何处以及哪个字段是空的,从而生成了异常?最好尝试/捕获容易出错的代码并实现obove IMO提供的解决方案
<%@ page isErrorPage="true" %>
...
${exception}
<%@ page isErrorPage="true" %>
...
<pre>${pageContext.out.flush()}${exception.printStackTrace(pageContext.response.writer)}</pre>
public final class Functions {

    private Functions() {}

    public static String printStackTrace(Throwable exception) {
        StringWriter stringWriter = new StringWriter();
        exception.printStackTrace(new PrintWriter(stringWriter, true));
        return stringWriter.toString();
    }

}
<?xml version="1.0" encoding="UTF-8" ?>
<taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

    <display-name>Custom Functions</display-name>    
    <tlib-version>1.0</tlib-version>
    <uri>http://example.com/functions</uri>

    <function>
        <name>printStackTrace</name>
        <function-class>com.example.Functions</function-class>
        <function-signature>java.lang.String printStackTrace(java.lang.Throwable)</function-signature>
    </function>
</taglib>
<%@ taglib prefix="my" uri="http://example.com/functions" %>
...
<pre>${my:printStackTrace(exception)}</pre>
try {
    chain.doFilter(request, response);
} catch (ServletException e) {
    log(e.getRootCause());
    throw e;
} catch (IOException e) { // If necessary? Usually not thrown by business code.
    log(e);
    throw e;
}