`

Java异常机制(日志处理)

阅读更多

本文转载,最有意思的是 if(e.getCause() instanceof MailSendException) 而e代表MailException。

1. 异常的种类

       Java异常机制是为了对程序中可能出现的已知错误进行捕获,并进行相应处理。从是否反馈给用户来看,存在三类异常:

数据库操作异常

系统异常:这类异常(如 应用服务器异常)由系统本身的低级异常引起,例如数据库连接失败、内存溢出、空指针异常等等,这类异常不需要出现在前台,因为用户看不懂也没有必要看到这些异常信息。这类异常需要在日志中进行完整记录以供日后开发人员进行查看分析。

 

应用异常:即自定义异常(业务异常,如 权限不够等),这类异常需要通过前台反馈给用户,友好提示用户当前操作异常。应用异常通过系统异常转换而来,例如新建用户时,发生主键冲突异常,则需要在UserinfoDao中将主键冲突异常捕获,并转换为应用异常,异常提示信息设为该用户名XXX已存在,请使用其它用户名,并将该异常信息反馈给前台。只要系统异常影响到的用户的当前操作,就必须给用户提示信息,比如系统后台发生错误,请稍后再试等。应用异常应按照提示方式的异常进行分类,对应不同的提示页面。

 

2. 日志的作用

    系统运行日志:记录系统的运行情况,跟踪代码运行时轨迹;

    异常和错误日志:记录异常堆栈信息,以供开发人员查看分析;

    业务日志:记录业务信息和用户操作,例如用户登录、删除数据、更新数据等。

 

3. 异常的处理原则

1、避免过大的try块,不要把不会出现异常的代码放到try块里面,尽量保持一个try块对应一个或多个异常。

2、细化异常的类型,不要不管什么类型的异常都写成Excetpioncatch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常,然后针对具体的异常类进行不同的处理。例如在DAO层中我们应该只捕获SQLExceptionDataAccessException(Spring自定义的数据访问异常类)这些数据库异常类,其他的异常NullPointExceptionNumberFormatException等应通过检测代码增加其健壮性来解决,而不应该通过try..catch(Exception e)语句捕获所有的异常。

3、不要把自己能处理的异常抛给别人,不要忽略捕获的异常,捕获到后要么处理,要么转译,要么重新抛出新类型的异常。。处理方式包括:

Ø  处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经处理好了异常

Ø  重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。

Ø  把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。

4、如果对catch块尽量保持一个块捕获一类异常,在catch语句中尽可能指定具体的异常类型,必要时使用多个catch

 

例:

      try {

      } catch (Exception e) {

           e.printStackTrace();

           log.error("UserinfoDao execute() failed");

}

这段代码捕获了异常,但实际上对异常并没有进行处理,可以算得上Java编程中的杀手。按照这个方式,在DAO层发生异常被忽略,Service层就认为DAO层运行正确,就不会回滚,事务控制就没有任何作用!!!

Ø  printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任。

Ø  日志尽量在系统中的各个出口,例如Action、调度方法等处统一记录,可减少工作量,况且日志"UserinfoDao execute() failed”并没有说明异常的详细信息,没有必要向日志输出这句话。

Ø  即使catch中加入throw new RuntimeException(e);语句。如果捕获的异常是RuntimeException,更没有必要将异常再次转化为RuntimeException,这样不仅异常的本身的类型丢失,重新定义异常也造成一定消耗。

所以该处的处理原则应是:如果该处异常需要能转化为业务异常反馈给用户,则需要捕捉低级异常并转换成业务异常上抛,否则不做任何处理!!!

 

 

 

6、不要用try...catch参与控制程序流程,异常控制的根本目的是处理程序的非正常情况。

 

 

 

4. 开发中异常的处理方式

 

本系统使用SSH框架,DAO+Service+Action三层架构,捕获原则是只有将低级系统异常转化为应用异常的需要才进行捕捉。

 

各层的处理方式如下:

 

DAO层:引发DAO异常的问题往往是不可恢复的,如数据连接失败,SQL语句存在语法错误,强制捕捉的检查型异常除了限制开发人员的自由度以外,并没有提供什么有意义的作用。因此,Spring的异常体系都是建立在运行期异常的基础上,这些异常都继承于DataAccessExceptionRuntimeException异常子类),所以,除了出于将低级系统异常转化为应用异常的需要,没有必要捕获异常,让DAO类自动上抛异常即可。

 

Service层:只捕获自定义应用异常,其他异常上抛。

 

Action:只捕获自定义应用异常,其他异常上抛。Struts2提供了异常拦截器,拦截器会将定义的异常捕获,记录日志,然后根据配置的异常的类型顺序跳转到相应的页面。配置如下:

 

struts.xml配置文件

<interceptor-ref name="defaultStack">

       <param name="exception.logEnabled">true</param><!--开启日志记录 -->

       <param name="exception.logLevel">error</param><!-- 日志级别为ERROR -->

</interceptor-ref>

<global-exception-mappings><!—异常类和跳转页面配置 -->

       <exception-mapping result="basicerror" exception="com.***.***.exception.BasicException"/>

       <exception-mapping result="error" exception="java.lang.Exception"/>

</global-exception-mappings>

 

 

 

com.***.***.exception.BasicException为自定义应用异常,如果客户端的请求执行过过程中产生com.***.***.exception.BasicException异常,则会自动转到basicerror页面,从而给用户相应的提示。

 

basicerror页面

<%@ page language="java" contentType="text/xml; charset=UTF-8"       pageEncoding="UTF-8"%>${exception.message }

 

 

 

 5. 自定义应用异常 

 

异常名称

说明

com.***.***.exception.BasicException

基础异常类,本系统中所有的自定义异常类均需继承本类

com.***.***.exception. DuplicateKeyException

主键冲突异常,继承BasicException

 

Userinfo save方法异常处理

@Override

       public void save(Userinfo entity) {

              try {

                     super.save(entity);

              } catch (DataIntegrityViolationException e) {

                     if(e.getCause().getCause() instanceof SQLException){

                            SQLException sqlE = (SQLException)e.getCause().getCause();

                            if(sqlE.getErrorCode()==1){//ORACLE主键冲突异常代码

                                   throw new DuplicateKeyException("用户名:"+entity.getUserid()+"已存在,请使用其他用户名");

                            }

                     }

              }

       }

 

 

 

6. 日志配置

 

系统中目前配置了三个日志记录器,一个为异常记录器,专门记录异常信息,日志文件到达一定大小后将产生新的日志文件,文件名称为exception.log,另一个为系统运行记录器,按照日期记录所有的日志信息。

分享到:
评论

相关推荐

    论文研究-基于分层分类的J2EE应用系统异常处理方法.pdf

    随着J2EE应用系统业务逻辑日益复杂和规模不断扩大,传统的异常处理仅依赖Java异常处理机制,缺失层次性和分类性,存在异常处理散乱、扩展困难和异常日志混乱等问题。从J2EE应用系统架构的层次性着手,建立异常层次...

    java动态日志注入工具anylog.zip

    anylog 是一个可以在代码的任意区域无入侵地加入日志的工具,适用于线上问题排查。 anylog 为开发人员提供一个易于使用的平台,帮助开发... 如果要深入了解spi机制,请自行google:java spi 标签:anylog

    JAVA_API1.6文档(中文)

    java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java....

    Java 1.6 API 中文 New

    java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util...

    JAVA上百实例源码以及开源项目

     Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,得到Graphics实例,得到Image实例,填充颜色数组数据,初始化颜色数组。...

    JAVA上百实例源码以及开源项目源代码

     Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,得到Graphics实例,得到Image实例,填充颜色数组数据,初始化颜色数组。...

    java开源包11

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包6

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包9

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包4

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包101

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包5

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包8

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包10

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java api最新7.0

    java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util...

    JavaAPI1.6中文chm文档 part1

    java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java....

    java开源包3

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    java开源包1

    Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...

    Java八股文最新消息中间件面试宝典

    第三个是开启消费者确认机制为auto,由spring确认消息处理成功后完成ack,当然也需要设置一定的重试次数,我们当时设置了3次,如果重试3次还没有收到消息,就将失败后的消息投递到异常交换机,交由人工处理

Global site tag (gtag.js) - Google Analytics