web-dev-qa-db-ja.com

JSPページでエラースタックトレースを印刷するにはどうすればよいですか?

Web.xmlで次のようなエラーページを設定しました。

 <error-page>
  <exception-type>Java.lang.Exception</exception-type>
  <location>/errors/error.jsp</location>
 </error-page>

ここで、JSPにエラーのスタックトレースを出力したいと思います(もちろん開発モードのみ)。 JSPページにエラーのスタックトレースを印刷するにはどうすればよいですか?このアプリケーションにはフレームワークを使用していません。そのため、プログラムではデフォルトのサーブレットAPIのみを使用できます。

22
newbie

内部で設定されたリクエストからパラメータを取得し、それを使用してcausemessageなどの他の情報を印刷および処理します。

<c:set var="exception" value="${requestScope['javax.servlet.error.exception']}"/>

スタックトレースを印刷する

<!-- Stack trace -->
<jsp:scriptlet>
  exception.printStackTrace(new Java.io.PrintWriter(out));
</jsp:scriptlet>

関連項目

20
Jigar Joshi

要求がエラーページに転送されると、コンテナによって次のパラメータが設定されます。

  • javax.servlet.error.status_code
  • javax.servlet.error.exception
  • javax.servlet.error.message
  • javax.servlet.error.request_uri
  • javax.servlet.error.servlet_name
  • javax.servlet.error.exception_type

エラーJSPでこれを行う、

<%request.getAttribute("javax.servlet.error.exception").printStackTrace(new Java.io.PrintWriter(out))%>;

またはその他エラーページがページディレクティブのようなエラーページとして定義されている場合、

<%@ page isErrorPage="true" import="Java.io.*"%>

exceptionスクリプト変数はJSPで宣言されます。次を使用して、スクリプトレットを使用してスクリプト変数を印刷できます。

exception.printStackTrace(new Java.io.PrintWriter(out));

または、

<jsp:scriptlet>
    exception.printStackTrace(response.getWriter())
</jsp:scriptlet>
21
Ramesh PVK

JSPスクリプトレットの使用は、10年以来実践されているものです。 avoid それが最善です。

すでにEL 2.2以降(Tomcat 7 +、JBoss AS 6 +、WildFly、GlassFish 3+など)を使用しており、${instance.method()}形式のメソッド式を新たにサポートしている場合は、これには100%ELを使用します。

最初に JspWriter#flush() を使用して明示的にJSPライターをフラッシュする必要があります。これにより、先行するすべてのJSPテンプレート出力が実際にサーブレット応答のライターに書き込まれます。

_${pageContext.out.flush()}
_

次に、 ServletResponse#getWriter()Throwable#printStackTrace() に渡すだけです。

_${exception.printStackTrace(pageContext.response.writer)}
_

完全な例:

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

既にEL 3.0(Tomcat 8 +、WildFly、GlassFish 4+など)を使用している場合は、ELステートメントを区切る新しいセミコロン演算子を使用して単一の式にすることもできます。

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

何らかの理由で_isErrorPage="true"_を使用できない場合(したがって_${exception}_暗黙的なオブジェクトは使用できません)、単に_${requestScope['javax.servlet.error.exception']}_に置き換えてください:

_<%@page pageEncoding="UTF-8" %>
...
<pre>${pageContext.out.flush()}${requestScope['javax.servlet.error.exception'].printStackTrace(pageContext.response.writer)}</pre>
_

まだEL 2.2を使用していない場合、最善の策はカスタムEL関数を作成することです。詳細は サーブレットからjspページに例外を転送する良い方法は何ですか?

以下は、より詳細な完全なエラーページの例です。

_<%@page pageEncoding="UTF-8" isErrorPage="true" %>
<%@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>
    <li>Stack trace: <pre>${pageContext.out.flush()}${exception.printStackTrace(pageContext.response.writer)}</pre></li>
</ul>
_
13
BalusC

役に立つかもしれません。
例外StackTraceがブラウザに表示されます

exception.printStackTrace(response.getWriter());  

または

<%
  try{
     int test = Integer.parseInt("hola");
  }catch(Exception e){
     **// HERE THE MAGIC BEGINS!!**
     out.println("<div id=\"error\">");
     e.printStackTrace(new Java.io.PrintWriter(out));
    out.println("</div>");
    **// THE MAGIC ENDS!!**
  }
%>

Error.jspの上部で<% page isErrorPage="true" %>を宣言すると、${exception}によってスローされた例外(したがって、そのゲッターもすべて)にアクセスできます。

<p>Message: ${exception.message}  

詳細を参照してください。 エラー画面へのエラーのマッピング

5
Sumit Singh

または、jspでスクリプトレットを使用しないようにするには、jstlを使用します。

<%@taglib prefix="c" uri="http://Java.Sun.com/jsp/jstl/core"%>
...

<c:set var="exception" value="${requestScope['javax.servlet.error.exception']}"/>

<c:if test="${exception != null}">
  <h4>${exception}</h4>
  <c:forEach var="stackTraceElem" items="${exception.stackTrace}">
    <c:out value="${stackTraceElem}"/><br/>
  </c:forEach>
</c:if>

理想的には、スクリプトレットはベストプラクティスとして許可されません。 web.xml構成を介してjspファイルのスクリプレットを明示的に防止します。

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
    <scripting-invalid>true</scripting-invalid>
  </jsp-property-group>
</jsp-config>
3
Brice Roncace

エラーページで、次の操作を行います。

<jsp:scriptlet>
    exception.printStackTrace(response.getWriter())
</jsp:scriptlet>

これには疑問がありますが、ユーザーは例外で何をするのでしょうか。エラーログに例外を書き込んで永続化して、ユーザーが苦情を申し立てた後に元に戻すことができるのはなぜですか?

3

スローされた例外オブジェクトは、「javax.servlet.error.exception」という名前のリクエスト属性として使用できます。したがって、JSPで次のように記述できます。

<% request.getAttribute("javax.servlet.error.exception").printStackTrace(new Java.io.PrintWriter(out); %>
2
socha23

Jstlコアライブラリを使用できます

1)JSPファイルの上にtablibをインポートする

<%@ taglib uri="http://Java.Sun.com/jsp/jstl/core" prefix="c" %>

2)タグを使用

<c:catch var="myExceptionObject">
    Code that might throw Exception
</c:catch>

<c:if test="${myExceptionObject} != null">
    There was an exception: ${myExceptionObject.message}
</c:if>
1

Error.jspに以下の行を追加します

<%Logger log = Logger.getLogger("error_jsp.class");
Exception e = (Exception)request.getAttribute("javax.servlet.error.exception");
log.debug(request.getAttribute("javax.servlet.error.message"));
e.printStackTrace();
log.debug(e.getStackTrace());%>
0
Ragu14