Java EE App的理想错误页面

时间:2010-08-24 03:06:16

标签: java jsp servlets exception-handling

我很难在我的应用程序中整合错误。目前,我的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 个答案:

答案 0 :(得分:4)

这段代码诚实hurts我的眼睛。这是一个通用的应该是什么样子。您可能会发现它很有用。

<%@ 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仅在您希望在JSP中具有${exception}(即request.getAttribute("exception")时才有用。在这种特殊情况下,您不需要它。 / p>

事实上,根本不要在catch区块前进。放手吧。它将由错误页面处理。

} catch (MyException ex) {
    log.error(ex.getMessage(), uivex);
    throw ex; // Or throw new ServletException(ex.getMessage(), ex);
}

答案 1 :(得分:1)

将所有详细信息放在日志中,并向用户显示一个模糊的消息,表明出现了问题,无论异常是什么。所以你的错误页面可能看起来像(引用twitter):

<%@ page isErrorPage="true" %>

Something went technically wrong. 

不要抓住&amp;前进 - 简单地让异常泡沫。正如您所说,另一种选择是制作两个包含公共内容的单独页面,并且仅在isErrorPage定义中有所不同。

答案 2 :(得分:1)

您可以创建自定义stackTrace jsp标记并将其包含在特殊错误页面中:

标记文件(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>

“报告此错误按钮可以提交堆栈跟踪或邮寄它!