Идеальная страница ошибки для приложения Java EE - PullRequest
2 голосов
/ 24 августа 2010

Мне сложно консолидировать ошибки в моем приложении.В настоящее время мой error.jsp выглядит следующим образом (частично):

 <%@ page isErrorPage="true" %>
 <%@page contentType="text/html"%>
 <%@page import="java.util.*"%>
 <%@page import="javax.servlet.*"%>
 <%@page import="javax.servlet.http.*"%>
 <%@page import="java.util.Calendar"%>
 <%@page import="java.text.SimpleDateFormat"%>

<html>
<%
String code = null, message = null, type = null, uri = null, time = null;
Object codeObj=null, messageObj=null, typeObj=null;
if (request.getAttribute("javax.servlet.error.status_code") != null)
    codeObj = request.getAttribute("javax.servlet.error.status_code");
if (request.getAttribute("javax.servlet.error.message") != null)
    messageObj = request.getAttribute("javax.servlet.error.message");
if (request.getAttribute("javax.servlet.error.exception_type")!=null)
    typeObj = request.getAttribute("javax.servlet.error.exception_type");

if (codeObj != null) code = codeObj.toString();
if (messageObj != null) message = messageObj.toString();
if (typeObj != null) type = typeObj.toString();
uri = (String) request.getAttribute("javax.servlet.error.request_uri");
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
time = sdf.format(cal.getTime());

String error = "Code:\t\t" + code + "\nType:\t\t" + type + "\nURL:\t\t" + uri + "\nTime:\t\t" + time +"\nMessage:\t" + message;
%>

Это прекрасно работает во всех сценариях, кроме !: Иногда в моем приложении я ловлю встроенные исключения в классе MyException сследующий код:

catch(MyException ex){
    log.error(ex.getMessage(), uivex);
    String originalURL = "/errorpages/error.jsp?errorcode=" + (ex.getMajor() + ex.getMinor()) + "&errormessage=" + ex.getMessage();
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(address);
    dispatcher.forward(request,response);   
}

Теперь проблема в том, что когда меня перенаправляют на страницу error.jsp ... Вместо того, чтобы видеть фактическую ошибку из MyException класса ... Я вижу NullPointerExceptionпотому что в javax.servlet.error.status_code ничего нет, а страница объявлена ​​как isErrorPage="true"

Что мне делать в этом случае?Одним из решений является создание совершенно другой страницы error.jsp (назовите ее error1.jsp) и пересылка исключений из класса MyException на эту страницу.Хотя хотелось бы, чтобы все было в одном месте.

Ответы [ 3 ]

4 голосов
/ 24 августа 2010

Честно говоря, этот код ранит мои глаза.Вот как должен выглядеть универсальный.Это может оказаться полезным.

<%@ page pageEncoding="UTF-8" %>
<%@ 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" />
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Error</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <h1>Error</h1>
        <p>Unfortunately an unexpected error has occurred. Below you can find the error details.</p>
        <h2>Details</h2>
        <ul>
            <li>Timestamp: <fmt:formatDate value="${date}" type="both" dateStyle="long" timeStyle="long" />
            <li>Action: <c:out value="${requestScope['javax.servlet.forward.request_uri']}" />
            <li>Exception: <c:out value="${requestScope['javax.servlet.error.exception']}" />
            <li>Message: <c:out value="${requestScope['javax.servlet.error.message']}" />
            <li>Status code: <c:out value="${requestScope['javax.servlet.error.status_code']}" />
            <li>User agent: <c:out value="${header['user-agent']}" />
        </ul>
    </body>
</html>

Кстати, @page isErrorPage полезно, только если вы хотите, чтобы ${exception} (то есть request.getAttribute("exception") было доступно в JSP. В данном конкретном случае вы неЭто не нужно.

И действительно, вообще не переадресовывайте в блок catch. Просто отпустите его. Это будет обработано страницей ошибок.

} catch (MyException ex) {
    log.error(ex.getMessage(), uivex);
    throw ex; // Or throw new ServletException(ex.getMessage(), ex);
}
1 голос
/ 24 августа 2010

Вы можете создать собственный тег jsp stackTrace и включить его в специальную страницу ошибки:

Файл тега (WEB-INF / tags / stackTrace.tag)

<%@tag description="Prints stack trace of the specified Throwable"
          pageEncoding="UTF-8"%>

<%-- content (prints stack trace) --%>
<%
      java.io.PrintWriter pOut = new java.io.PrintWriter(out);
      try {
         // The Servlet spec guarantees this attribute will be available
         Throwable err = (Throwable) 
             request.getAttribute("javax.servlet.error.exception");

         if(err != null) {
            if(err instanceof ServletException) {
               // It's a ServletException: we should extract the root cause
               ServletException se = (ServletException) err;
               Throwable rootCause = se.getRootCause();
               if(rootCause == null) {
                  rootCause = se;
               }
               out.println("** Root cause is: " + rootCause.getMessage());
               rootCause.printStackTrace(pOut);
            }else {
               // It's not a ServletException, so we'll just show it
               err.printStackTrace(pOut);
            }
         }else {
            out.println("No error information available");
         }

         // Display cookies
         out.println("\nCookies:\n");
         Cookie[] cookies = request.getCookies();
         if(cookies != null) {
            for(int i = 0; i < cookies.length; i++) {
               out.println(cookies[i].getName() + "=[" + 
                   cookies[i].getValue() + "]");
            }
         }

      }catch(Exception ex) {
         ex.printStackTrace(pOut);
      }
%>

error.jsp может выглядеть так: (добавьте немного юмора, если ваше приложение несколько случайное)

<%@ page isErrorPage="true" %>
<html>
   <head>
    <title>Error</title>
   </head>
   <body>
      <div>
         <textarea class="para error">
            Aww Snap!! :( Something went wrong where it was not supposed to. 
            Must be something
            <a href="http://en.wikipedia.org/wiki/Jack_the_Ripper">Jack</a> did!
            Please report this to the dev team.

            <!-- 
               <util:stackTrace />
            -->

         </p>
      </div>
   </body>
</html>

Кнопка «Сообщить об ошибке» может отправить трассировку стека или отправить ее по почте!

1 голос
/ 24 августа 2010

Поместите все подробности в журналы и покажите пользователю только смутное сообщение о том, что что-то пошло не так, независимо от того, что является исключением.Таким образом, ваша страница с ошибкой может выглядеть (цитируя твиттер):

<%@ page isErrorPage="true" %>

Something went technically wrong. 

И не перехватывать и пересылать - просто дайте пузырю исключения.Другой альтернативой, как вы говорите, является создание двух отдельных страниц, которые содержат общий контент и отличаются только определением isErrorPage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...