開發階段,異常堆棧直接輸出頁面便於調試;但生產環境這極不友好——非技術用戶看到亂碼般的堆棧會恐慌失措。本文提供基於 web.xml 錯誤頁配置的簡潔解決方案,並探討進階交互式錯誤展示思路。
<!-- 404.html -->
<body>
所訪問的資源不存在:對不起,所請求的資源不存在!<br>
</body>
<!-- 500.html -->
<body>
服務器內部錯誤:對不起,服務器忙!<br>
</body>
<web-app version="2.4" xmlns="https://java.sun.com/xml/ns/j2ee" ...>
<servlet>
<servlet-name>ErrServlet</servlet-name>
<servlet-class>lavasoft.errtest.ErrServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrServlet</servlet-name>
<url-pattern>/servlet/ErrServlet</url-pattern>
</servlet-mapping>
<!-- 關鍵:錯誤碼映射 -->
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.html</location>
</error-page>
</web-app>
public class ErrServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
throw new RuntimeException("------"); // 強制觸發 500
}
}
404.html/servlet/ErrServlet → 拋出異常 → 容器返回 500 → 自動轉向 500.html靜態頁雖簡單但信息單薄。生產環境建議:
<details> 或隱藏 <div> 中)<!-- 500-advanced.jsp -->
<body>
<h2>系統暫時不可用,請稍後重試</h2>
<button onclick="document.getElementById('stack').style.display='block'">查看技術詳情</button>
<div id="stack" style="display:none; font-family:monospace; white-space:pre-wrap;">
${pageContext.exception.stackTrace} <!-- JSTL 輸出堆棧 -->
</div>
<p>錯誤參考 ID: ${requestScope['javax.servlet.error.request_uri']}-${System.currentTimeMillis()}</p>
</body>
web.xml 中映射:
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/500-advanced.jsp</location>
</error-page>
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 靜態 HTML | 零依賴、極簡、容器級處理 | 信息單一、無調試輔助 | 簡單項目、靜態資源 404 |
| 動態 JSP + JS | 信息分層、開發運維友好、可集成日誌追蹤 ID | 需容器支持 JSP、略增複雜度 | 生產環境標準配置 |
| 全局異常處理器 | 統一攔截、可編程控制、支持 REST API 錯誤碼 | 需框架支持 | Spring MVC、JAX-RS 等框架項目 |