4

このようにweb.xmlに何かを入れることができることを知っています

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

ただし、jsp ページは、例外が正確に何であるかを取得できないため、構造的な情報を表示しません。さまざまな例外をさまざまなページに転送できることはわかっていますがexception-type、web.xml に記述するには多すぎます。404 のようなエラーを処理するには、1 ページで十分であり、別のページで十分であることを願っています。

では、例外情報を jsp ページに渡すにはどうすればよいでしょうか。セッションを使用しますか?

理想的な状況は、ページが例外情報を取得し、ユーザーに例外を明らかにすることなく、それに関連するメッセージを表示することです。代わりに、後で参照できるようにファイルに記録できます。これを達成するための最良のアプローチは何ですか?ありがとう。

4

2 に答える 2

12

例外に関する情報は、いくつかのリクエスト属性によってすでに利用可能です。これらすべての属性の名前は、RequestDispatcherjavadocで確認できます。

つまり、この 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>

さらに、次の有用な情報を表示することもできます。

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

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

EL 2.2以降を使用している場合のみ、以下のようにスタックトレースを出力できます:

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

または、まだ EL 2.2 を使用していない場合は、そのためのカスタム EL 関数を作成します。

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>

例外のロギングに関しては、最も簡単な場所は、URL パターンにマップされ、基本的に次のことを行うフィルターです。/*

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;
}
于 2012-09-04T11:58:02.540 に答える
0

はい、私の意見では、セッションは現在のリクエストに関連する例外を保存するのに適しています。

処理が終了したら、例外をクリアすることを忘れないでください。

また、例外の代わりに、バッキング コードからプレゼンテーション レイヤーにエラー コードを渡すことができます。このエラー コードは、プロパティ ファイルを使用して、ユーザーにとって意味のある完全なエラーに変換できます。

于 2012-09-04T06:42:24.753 に答える