转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6403033.html
在项目中的应用见: https://github.com/ygj0930/CoupleSpace
Java本身定义了两个throwable类的子类,error类与exception类。而这些原生的异常除非是开发人员,否则一般人是看不懂的。那怎么办呢?我们可以在开发时,继承异常类,来自定义异常,并且在View层统一处理异常将之转变为用户能懂的信息以及控制项目跳过异常操作,维持项目的正常运行。
一:自定义Error类或Exception类
public class BaseError extends Error { protected String key; protected Object[] args; /** * * @param key 异常提示信息 */ public BaseError(String key) { super(key); this.key = key; } /** * * @param key 异常提示信息 * @param cause 异常对象 */ public BaseError(String key, Throwable cause) { super(key, cause); this.key = key; } /** * * @param key 异常提示信息 * @param args 在抛异常时把某些数据也抛给异常处理者 */ public BaseError(String key, Object ... args) { super(key); this.key = key; this.args = args; } /** * * @param key 异常提示信息 * @param cause 异常对象 * @param args 在抛异常时把某些数据也抛给异常处理者 */ public BaseError(String key, Throwable cause, Object ... args) { super(key, cause); this.key = key; this.args = args; } //在捕获并处理异常时,获取异常的详细信息。比如在filter层统一处理异常时通过以下方法获取所处理异常的信息来在view层作出应答 public String getKey() { return key; } public Object[] getArgs() { return args; } }
public class MyException extends RuntimeException { protected String key; protected Object[] args; public MyException(String key) { super(key); this.key = key; } public MyException(String key, Throwable cause) { super(key, cause); this.key = key; } public MyException(String key, Object ... args) { super(key); this.key = key; this.args = args; } public MyException(String key, Throwable cause, Object ... args) { super(key, cause); this.key = key; this.args = args; } public String getKey() { return key; } public Object[] getArgs() { return args; } }
Error和Exception都是实现了Throwable接口的,二者的区别主要在于:程度的不同。
Error是系统机器的错误,比如虚拟机内存溢出等严重问题,通常出现系统异常的时候项目都已经要停止运行的了。一般不会对error进行捕捉和处理,因为这些问题不是代码可以修复的。
而Exception一般是运行过程中出现的逻辑错误、误操作等轻度的问题,不会导致项目停止运行,只不过引发异常的操作不能正常完成而已。对于异常,我们一般进行捕捉处理,转化为runtime异常的子类进行抛出,在过滤器统一进行处理以提供良好的用户体验并维持项目继续运。
二:在项目代码的try-catch()块中包装异常
在项目代码中,有可能出现异常、运行错误的地方,用try-catch语句捕捉异常。把异常记录到日志后,再把捕获的异常包装成自定义异常(注意:自定义的异常必须是继承自RuntimeException的才可以抛出。其他Exception的不可以的)进行抛出。在一个filter处进行统一的拦截处理,作出用户能理解的处理提示并进行有效的异常控制,以免项目崩溃,使得用户跳过异常操作继续使用项目。
比如:
try{ 数据库操作 } catch (ClassNotFoundException e) { logger.error("ClassNotFoundException in ArticleDAO!", e); throw new MyException("ClassNotFoundError", e); } catch (SQLException e) { logger.error("SQLException in ArticleDAO!", e); throw new MyException("SQLError", e); }
三:配置一个过滤器位于过滤链的顶端,对所有进出项目的异常进行捕捉处理。
根据所捕捉到的异常不同来进行不同的提示信息,并控制项目在发生异常后如何响应,以维持项目继续运行。
比如:
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { String err=""; try { arg2.doFilter(arg0, arg1); }catch(Error e){ err="系统错误"; }catch(MyException e){ err=e.getKey(); }catch (Exception e) { err="系统异常"; } PrintWriter out = arg1.getWriter(); if(!err.equals("")){ out.print("<script>alert('"+err+"');window.location='index.jsp';</script>"); out.close();} }
切记,这个过滤器需配置在过滤链的第一位!