本文介绍了将异常从 servlet 转发到 jsp 页面的好方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know I can put something in the web.xml like this

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

然而,jsp 页面不会显示任何建设性信息,因为它不会得到究竟是什么异常.我知道我们可以通过各种 exception-type 将不同的异常转发到不同的页面,但是在 web.xml 中写太多了.我希望一页就足够了,另一页可以用来处理 404 之类的错误.

However the jsp page won't show any contructive information since it won't get what exactly the exception is. I know we can have different exceptions forwarded to different pages by various exception-type but that's too much to write in web.xml. I hope one page is enough and another for handling errors like 404.

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

So how should I pass the exception information to the jsp page? Use session?

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

The ideal situation might be the page gets the exception info and show some relevant messages about it without revealing the exception to the users. Instead it could log it into a file for future reference. What is the best approach to achieve this? Thanks.

推荐答案

有关异常的信息已经可通过多个请求属性获得.您可以在 RequestDispatcher javadoc:

The information about the exception is already available by several request attributes. You can find the names of all those attributes in the RequestDispatcher javadoc:

  • ERROR_EXCEPTION - javax.servlet.error.exeption
  • ERROR_EXCEPTION_TYPE - javax.servlet.error.exception_type
  • ERROR_MESSAGE - javax.servlet.error.message
  • ERROR_REQUEST_URI - javax.servlet.error.request_uri
  • ERROR_SERVLET_NAME - javax.servlet.error.servlet_name
  • ERROR_STATUS_CODE - javax.servlet.error.status_code

所以,简而言之,这个 JSP 示例应该显示所有可能的异常细节:

So, in a nutshell, this JSP example should display all the possible exception detail:

<%@ 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>

此外,您还可以显示这些有用的信息:

Additionally, you could also show this useful information:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<jsp:useBean id="date" class="java.util.Date" />
...
<ul>
    <li>Timestamp: <fmt:formatDate value="${date}" type="both" dateStyle="long" timeStyle="long" /></li>
    <li>User agent: <c:out value="${header['user-agent']}" /></li>
</ul>

当您将页面标记为错误页面时,具体的 Exception 实例本身在 JSP 中仅作为 ${exception} 可用:

The concrete Exception instance itself is in the JSP only available as ${exception} when you mark the page as an error page:

<%@ page isErrorPage="true" %>
...
${exception}

仅当您使用 EL 2.2 或更新版本时,您才可以打印其堆栈跟踪,如下所示:

Only if you're using EL 2.2 or newer, then you can print its stacktrace as below:

<%@ page isErrorPage="true" %>
...
<pre>${pageContext.out.flush()}${exception.printStackTrace(pageContext.response.writer)}</pre>

或者如果你还没有使用 EL 2.2,那么创建一个 自定义 EL 函数:

Or if you're not on EL 2.2 yet, then create a custom EL function for that:

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();
    }

}

/WEB-INF/functions.tld中注册的:

<?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>

至于记录异常,最简单的地方是 filter 映射到 URL 模式/* 并基本上执行以下操作:

As to the logging of the exception, easiest place would be a filter which is mapped on an URL pattern of /* and does basically the following:

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;
}

这篇关于将异常从 servlet 转发到 jsp 页面的好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 20:23