浅析Java Web错误/异常处理页面

发生服务器 500 异常,如果默认方式处理,则是将异常捕获之后跳到 Tomcat 缺省的异常页面,如下图所示。

不论哪个网站都是一样的,所以为了满足自定义的需要,Tomcat 也允许自定义样式的。也就是在 web.xml 文件中配置:

<error-page>
  <error-code>500</error-code>
  <location>/error.jsp</location>
</error-page>

首先说说自带的逻辑。如果某个 JSP 页面在执行的过程中出现了错误, 那么 JSP 引擎会自动产生一个异常对象,如果这个 JSP 页面指定了另一个 JSP 页面为错误处理程序,那么 JSP 引擎会将这个异常对象放入到 request 对象中,传到错误处理程序中。如果大家有写 Servlet 的印象,这是和那个转向模版 JSP 的 javax.servlet.forward.request_uri 一个思路,保留了原请求的路径而不是 JSP 页面的那个路径。在错误处理程序里,因为 page 编译指令的 isErrorPage 属性的值被设为 true,那么 JSP 引擎会自动声明一个 exception 对象,这个 exception 对象从 request 对象所包含的 HTTP 参数中获得。

request 对象中包含的异常信息非常丰富,如下所示:

你可以用 Java 语句 request.getAttribute("javax.servlet.error.status_code") 获取,也可以在 JSP 页面中通过 EL 表达式来获取,如 ${requestScope["javax.servlet.error.status_code"]}。
这个自定义错误页面虽然简单,JSP 本身也有很好的封装结果,我也看过别人不少的资源,但细究之下也有不少“学问”,于是我想重新再”磨磨这个轮子“——首先 location 是一个 jsp 页面,也可以是 servlet,不过万一 servlet 也有可能启动不起来的话那就使用简单的 JSP 页面就好了。我们通过 JSP 页面定义内部类的方法,达到页面与逻辑的分离(无须编写 servlet)。其余的思路如下:

在 JSP 里面完成 ErrorHandler 类,另有页面调用这个 ErrorHandler 类
不但可以接受 JSP 页面的错误,也可接受 servlet 的控制器传递的错误,并且提取尽量多信息
全部内容先写到内存,然后分别从两个输出流再输出到页面和文件
把错误信息输出到网页的同时,简单加几句话,可以把网页上的信息也写一份到数据库或者文本
可以返回 HTML/JSON/XML
实现代码如下:

/**
 * 异常处理类
*/
class ErrorHandler {
  // 全部内容先写到内存,然后分别从两个输出流再输出到页面和文件
  private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  private PrintStream printStream = new PrintStream(byteArrayOutputStream); 

  /**
   * 收集错误信息
   * @param request
   * @param exception
   * @param out
   */
  public ErrorHandler(HttpServletRequest request, Throwable exception, JspWriter out) {
    setRequest(request);
    setException(exception); 

    if(out != null) {
      try {
        out.print(byteArrayOutputStream); // 输出到网页
      } catch (IOException e) {
        e.printStackTrace();
      }
    } 

     log(request); 

    if(byteArrayOutputStream != null)
      try {
        byteArrayOutputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    if(printStream != null) printStream.close();
  } 

  /**
   *
   * @param request
   */
  private void setRequest(HttpServletRequest request) {
    printStream.println();
    printStream.println("用户账号:" + request.getSession().getAttribute("userName"));
    printStream.println("访问的路径: "  + getInfo(request, "javax.servlet.forward.request_uri", String.class));
    printStream.println("出错页面地址: " + getInfo(request, "javax.servlet.error.request_uri", String.class));
    printStream.println("错误代码: "   + getInfo(request, "javax.servlet.error.status_code", int.class));
    printStream.println("异常的类型: "  + getInfo(request, "javax.servlet.error.exception_type", Class.class));
    printStream.println("异常的信息: "  + getInfo(request, "javax.servlet.error.message", String.class));
    printStream.println("异常servlet: " + getInfo(request, "javax.servlet.error.servlet_name", String.class));
    printStream.println(); 

    // 另外两个对象
    getInfo(request, "javax.servlet.jspException", Throwable.class);
    getInfo(request, "javax.servlet.forward.jspException", Throwable.class); 

    Map<String, String[]> map = request.getParameterMap(); 

    for (String key : map.keySet()) {
      printStream.println("请求中的 Parameter 包括:");
      printStream.println(key + "=" + request.getParameter(key));
      printStream.println();
    } 

    for (Cookie cookie : request.getCookies()){ // cookie.getValue()
      printStream.println("请求中的 Cookie 包括:");
      printStream.println(cookie.getName() + "=" + cookie.getValue());
      printStream.println();
    } 

  } 

  /**
   *
   * @param exception
   */
  private void setException(Throwable exception) {
    if (exception != null) {
      printStream.println("异常信息");
      printStream.println(exception.getClass() + " : " + exception.getMessage());
      printStream.println(); 

      printStream.println("堆栈信息");
      exception.printStackTrace(printStream);
      printStream.println();
    }
  } 

    /**
     *
     * @param request
     */
    private void log(HttpServletRequest request) {
      File dir = new File(request.getSession().getServletContext().getRealPath("/errorLog"));
      if (!dir.exists()) {
        dir.mkdir();
      } 

      String timeStamp = new java.text.SimpleDateFormat("yyyyMMddhhmmssS").format(new Date());
      File file = new File(dir.getAbsolutePath() + File.separatorChar + "error-" + timeStamp + ".txt"); 

//       try(FileOutputStream fileOutputStream = new FileOutputStream(file);
//         PrintStream ps = new PrintStream(fileOutputStream)){// 写到文件
//         ps.print(byteArrayOutputStream);
//       } catch (FileNotFoundException e) {
//         e.printStackTrace();
//       } catch (IOException e) {
//         e.printStackTrace();
//       } catch (Exception e){
//         e.printStackTrace();
//       }
    } 

    /**
     *
     * @param request
     * @param key
     * @param type
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T> T getInfo(HttpServletRequest request, String key, Class<T> type){
      Object obj = request.getAttribute(key);
      return obj == null ? null : (T) obj;
    }
}

这样就可以完成异常的控制了。下面定义 web.xml,让 tomcat 出错引向我们刚才指定的页面 error.jsp

<!-- 404 页面不存在错误 -->
<error-page>
  <error-code>404</error-code>
  <location>/WEB-INF/jsp/common/default/error.jsp</location>
</error-page>
<!-- // --> 

<!-- 500 服务器内部错误 -->
<error-page>
  <error-code>500</error-code>
  <location>/WEB-INF/jsp/common/default/error.jsp</location>
</error-page>
<!-- // -->

我们安排一个默认的页面如下

源码如下:

<%@page pageEncoding="UTF-8" isErrorPage="true"%>
<%@ include file="/WEB-INF/jsp/common/ClassicJSP/util.jsp"%>
<!DOCTYPE html>
<html>
<head>
  <title>错误页面</title>
  <style>
    body {
      max-width: 600px;
      min-width: 320px;
      margin: 0 auto;
      padding-top: 2%;
    } 

    textarea {
      width: 100%;
      min-height: 300px;
    } 

    h1 {
      text-align: right;
      color: lightgray;
    } 

    div {
      margin-top: 1%;
    }
  </style>
</head>
<body>
  <h1>抱 歉!</h1>
  <div style="padding:2% 0;text-indent:2em;">尊敬的用户:我们致力于提供更好的服务,但人算不如天算,有些错误发生了,希望是在控制的范围内……如果问题重复出现,请向系统管理员反馈。</div>
  <textarea><%
      new ErrorHandler(request, exception, out);
      %></textarea>
  <div>
    <center>
      <a href="${pageContext.request.contextPath}">回首页</a> | <a href="javascript:history.go(-1);">上一页</a>
    </center>
  </div>
</body>
</html> 

以上就是本文的全部内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • Java Web开发项目中中文乱码解决方法汇总

    Java Web项目中,解决中文乱码方法总结如下 第一种情况:调用jsp页面中文显示乱码 问题描述:通过浏览器调用jsp页面,在浏览器中显示的中文内容出现乱码. 解决方法:首先确认本jsp在编辑器中保存文件内容时,使用的是utf-8的编码格式,然后在jsp页面的开始处添加<%@ pageEncoding="utf-8"%>就可以解决这种中文乱码问题 第二种情况:调用servlet页面显示乱码 问题描述:通过浏览器调用servlet,servlet在浏览器中显示的内容出现乱码

  • 关于javaWeb中405错误的解决方法

    今天写了一个servlet,可是一直405报错,开始以为web.xml里面的servlet配置有问题,可是那样的话应该报404错误啊 最后才发现在重写doPost和doGet方法的时候,写成了dopost和doget,因为java对大小写很敏感,故相当于没有重新httpservelt里面的方法. 反思:编程需谨慎!!! 以上这篇关于javaWeb中405错误的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • 深入探讨JAVA中的异常与错误处理

    异常与错误: 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它.Java中使用异常类来表示异常,不同的异常类代表了不同的异常.但是在Java中所有的异常都有一个基类,叫做Exception. 错误: 它指的是一个合理的应用程序不能截获的严重的问题.大多数都是反常的情况.错误是VM的一个故障(虽然它可以是任何系统级的服务).

  • Tomcat正常启动,访问所有页面均报404异常,404异常总结分析

    404异常,很常见,大多情况是路径错误.web.xml文件映射路径写错.服务器设置.servlet的jar包未导进去或者没有随项目发布等等. 如果是路径错误,仔细检查即可解决问题. 服务器没设置好也会报这个错误,这一般是新手刚开始学时遇到的问题,就是要把eclipse中的tomcat的server location设置为use tomcat installation,在eclipse界面双击tomcat server见如图设置: 如果是servlet的jar包问题,则通过build path引入

  • 浅析Java Web错误/异常处理页面

    发生服务器 500 异常,如果默认方式处理,则是将异常捕获之后跳到 Tomcat 缺省的异常页面,如下图所示. 不论哪个网站都是一样的,所以为了满足自定义的需要,Tomcat 也允许自定义样式的.也就是在 web.xml 文件中配置: <error-page> <error-code>500</error-code> <location>/error.jsp</location> </error-page> 首先说说自带的逻辑.如果某

  • 深入浅析java web log4j 配置及在web项目中配置Log4j的技巧

    在上篇文章给大家介绍了Java log4j详细教程,本文给大家介绍java web log4j配置及web项目中配置log4j的技巧.具体详情请看下文吧. 首先给大家提供log4j.jar下载:http://logging.apache.org/log4j/1.2/download.html 一.java web项目使用log4j 1.在web.xml文件中添加 <!-- 配置log4j --> <context-param> <param-name>webAppRoo

  • 浅析Java中的异常处理机制

    异常处理机制 1.抛出异常 2.捕获异常 3.异常处理五个关键字: try.catch.finally.throw.throws 注意:假设要捕获多个异常:需要按照层级关系(异常体系结构) 从小到大! package exception; /** * Java 捕获和抛出异常: * 异常处理机制 * 1.抛出异常 * 2.捕获异常 * 3.异常处理五个关键字 * try.catch.finally.throw.throws * 注意:假设要捕获多个异常:需要按照层级关系(异常体系结构) 从小到大

  • Java Web实现登录页面验证码验证功能

    一.验证码 验证码本质上是一张图片,图片内容会随着程序的运行而随机生成 验证码的作用:防止应用恶意发送数据,一定程度上避免了恶意程序对网站的攻击. 验证码本质上是一张图片,图片内容的准确解析不容易用程序来实现. 验证码的绘制:绘制验证码图片不仅仅需要随机生成要绘制的内容,同时要配合Java中与绘图有关的一套API来完成. 二.效果演示 验证码Demo 三.给出完整代码 (1)服务器端代码ActionServlet.java package session; import java.io.IOEx

  • Java Web 登录页面的实现代码实例

    代码如下~ 内有详细解释,最后有照片! <html> <script type="text/javascript"> function inUser(){ username_mess.style.visibility="visible"; } function outUser(){ //获取name 为 usesrname 的文本 u=f1.username.value; f1.username.style.border="1px

  • JSP学习之Java Web中的安全控制实例详解

    本文实例讲述了JSP学习之Java Web中的安全控制.分享给大家供大家参考.具体如下: 一.目标: ① 掌握登录之后的一般处理过程: ② 能够为每个页面添加安全控制: ③ 能够共享验证代码: ④ 使用过滤器对权限进行验证: ⑤ 能够对文件的局部内容进行验证: ⑥ 掌握安全验证码的基本实现方式: ⑦ 通过异常处理增强安全性. 二.主要内容: ① 通过修改前面的登录功能,分别对管理员和普通用户的登录进行处理: ② 为管理员才能访问的页面添加控制: ③ 共享各个页面中的控制代码,使用专门的文件,然后

  • SpringBoot详解实现自定义异常处理页面方法

    目录 1.相关介绍 2.代码实现 3.运行测试 1.相关介绍 当发生异常时, 跳转到我们自定义的异常处理页面. SpringBoot中只需在静态资源目录下创建一个error文件夹, 并把异常处理页面放入其中, 页面的命名与异常错误代码对应, 如404.html, 500.html. 5xx.html可以对应所有错误代码为5开头的错误 默认静态资源目录为类路径(resources)下的: /static /public /resources /META-INF/resources 2.代码实现 H

  • JSP建立错误页页面并自动跳转

    在各个常用的web站点中,经常会发现这样一个功能:当一个页面出错后,会自动跳转到一个页面上进行错误信息的提示. 想要完成错误页的操作,则一定要满足两个条件: 1.指定错误出现时的跳转页,通过errorPage属性指定: 2.错误处理页必须有明确的标识,通过isErrorPage属性指定. 下面就是错误页:errorPage.jsp 代码如下: <%@ page language="java" import="java.util.*" pageEncoding=

  • Servlet+JavaBean+JSP打造Java Web注册与登录功能

    采用Java Web所实现的MVC结构图如下,其中控制器部分采用Servlet来实现,模型部分采用JavaBean来实现,而大部分的视图采用Jsp页面来实现. 思想基础 JSP+JavaBean两层结构工作原理应该是比较熟悉的,也比较好理解. 但是有一点必须要清楚就是用户通过浏览器来发送网页的请求,此请求到达服务器后在服务器端查找对应的网页,如果是首次请求(第二次就不用解释执行了),对于JSP来说要生成Servlet,然后通过Servlet引擎来执行 Servlet,把调用JavaBean的结果

  • AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】

    本文实例讲述了AngularJS实现与Java Web服务器交互操作的方法.分享给大家供大家参考,具体如下: AngularJS是Google工程师研发的产品,它的强大之处不是几句话就能描述的,只有真正使用过的人才能体会到,笔者准备在这篇文章中,以一个简单的登录校验的例子说明如何使用AngularJs和Web服务器进行交互. 准备工作 1.下载angular js库. 官网下载地址:https://angularjs.org/ 或者点击此处本站下载. 2.开发环境准备,由于是和Tomcat服务器

随机推荐