|
|
|
发新文章 |
|
|
Struts异常处理(原创) 异 常是当JVM(JAVA虚拟机)在执行应用程序的某个方法的时候遇到的非正常现象,JVM就会生成一个异常对象,抛给客户以便客户进行异常处理. Struts框架的异常处理机制建立在java异常处理的基础之上.在研究Struts异常处理之前,先回顾一下java异常处理原理,理解java虚拟 机JVM的异常处理过程有助于应用设计正确的异常处理方法.处理异常需要JVM付出不小的开销,所以用于必须慎重使用. JAVA 异常是在java程序运行的时候遇到非正常的情况而创建的对象,它封装了异常信息,java异常的根类为java.lang.Throwable,整个类 有两个直接子类java.lang.Error和java.lang.Exception.Error是程序本身无法恢复的严重错误.Exception 则表示可以被程序捕获并处理的异常错误.JVM用方法调用栈来跟踪每个线程中一系列的方法调用过程,该栈保存了每个调用方法的本地信息.对于独立的 JAVA程序,可以一直到该程序的main方法.当一个新方法被调用的时候,JVM把描述该方法的栈结构置入栈顶,位于栈顶的方法为正确执行的方法.当一 个JAVA方法正常执行完毕,JVM回从调用栈中弹处该方法的栈结构,然后继续处理前一个方法.如果java方法在执行代码的过程中抛出异常,JVM必须 找到能捕获异常的catch块代码.它首先查看当前方法是否贼这样的catch代码块,如果存在就执行该catch代码块,否则JVM回调用栈中弹处该方 法的栈结构,继续到前一个方法中查找合适的catch代码块.最后如果JVM向上追到了main()方法,也就是一直把异常抛给了main()方法,仍然 没有找到该异常处理的代码块,该线程就会异常终止,如果该线程是主线程,应用程序也随之终止,此时JVM将把异常直接抛给用户,在用户终端上会看到原始的 异常信息.回顾完了JAVA的异常处理机制,就要开始研究Struts的异常处理了. Struts 框架在视图层和控制层提供了对异常处理的支持.Struts的控制器负责捕获各种异常,包括控制器运行中本身抛出的异常,以及调用模型的业务方法的异常. 当异常被控制器捕获的时候,在异常处理代码块中,创建描述异常信息的ActionMessage对象把它保存在ActionMessages或者它的子类 ActionErrors对象中,然后把它保存在特定的范围内,比如request或session.接下来在视图层
标签检索特定范围的ActionMessages对象,把本地化错误消息输出到页面上.这种异常处理机制可以避免用户看到原始的 java异常信息.可以更友好的把错误信息展示给用户. Struts 框架处理异常是以JVM的异常处理机制为基础的,尽管它提供了强大的通用错误处理机制,但是不能保证捕获到所有的异常或者错误.当错误发生的时候,如果 Struts不能处理这种异常或者错误,就把错误抛给JavaWeb容器.容器先查看是否在Web应用发布描述文件中配置了元素,如果存在该元素就返回元素的子元素指定的错误页面,否则就会把错误直接抛给用户.下面简单介绍一 Struts几个重要的类的异常处理机制,如果想了解这几个类的更深的异常机制,建议查看Struts源代码. 1) ActionServlet类的peocess()方法不捕获任何异常,仅仅声明向上层调用方法抛出异常. 2) RequestProcessor类是Struts框架处理异常的核心组件. 3) ExceptionHandler类是默认的异常处理类,它的execute()方法负责处理异常. 根据打造技术Blog,寻求JAVA精髓! Servlet规范,当容器捕获到异常的时候,将查看是否在Web.xml中配置了相应的元素,如果存在,就会返回其子元素指定的错误页面.举个简单明了的例子如下: 500 /error.jsp javax.servlet.ServletException /error.jsp Struts框架也允许以配置的方式来处理异 常,配置方法可以避免在Action类中通过硬编码来处理异常,提高应用的灵活性,可重用性和可维护性.对于Action类的execute()方法抛出 的异常会先查找异常处理元素,如果是被嵌套在元素中就表示是全局异常处理元素,对所有的Action都适用.如果是嵌套在元素中,就表示局部的异常处理元素,仅对当前的Action适用.阐 述一下元素的属性: 1) type:指定待处理的异常类 2) handler:指定异常处理类.默认是ExceptionHandler.如果自己要定义必须继承它 3) path:指定转发路径 4) key:指定错误消息key.根据这个key到ResourceBundle中寻找匹配的消息文本 5) bundle:指定ResourceBundle,如果没设置将使用哦么人的ResourceBundle 6) scope:指定ActionMessages对象的存放范围,默认request,也可以设置session Struts框架提供了强大的异常处理功能,Struts控制器负责捕获异常,并把异常包装与 ResourceBundle绑定的 ActionMessages对象,在视图层
标签能够显示出来,主要可以通过配置的方式和编程的方式实现,这里不推 荐用编程的方法,可以增强程序的灵活性,可重用性,可维护性. (网友们的支持,是我继续写技术文章的动力!) Struts的异常处理机制总的来说,在struts新的版本中加入了对异常的处理,称之为:Exception Handling,标志着作为一个整体的解决框架,struts原来越趋于成熟。 通 常来说,以前在用struts开发的过程中,对于异常的处理,主要是采用手动处理的方式:如通过try/catch等等捕获异常,然后定制个性化的比较详 细的错误信息放进ActionError中,然后在具体的返回页面中把这些错误信息反馈给用户(包括开发员)。异常原始的信息不管是最终用户还是开发员都是不希望看到的。 下面着重讲一下在struts中是如何通过配置文件来解决异常。 Struts中的Exception Handleing不难,简单高效是业内给其的一个比较好的评价。 通过配置文件(主要是struts-config.xml)来定制异常处理,就象定义formbean一样,定制异常也有两种方法,姑且把它分为:“全局异常”和“局部异常”。 全局异常,定义方法如下: ………… ………… 上 述代码在struts-config.xml中定义了一个全局异常,它的作用是抛出InvalidiItemsCatalogNameException (本处的意思是当在添加商品分类的时候发现该类别已经存在)异常的时候返回到error.jsp中,并且携带自定的比较规范的异常信息 expired.InvalidItemsCatalogName,expired.InvalidItemsCatalogName可以在应用程序的资源配置文件中找到,如: expired.InvalidItemsCatalogName=你要添加的商品类别已经存在,请添加新的类别! 局部异常,定义方法如下: ………… ………… (关于Tiles的内容参看我的另一篇文章“Struts使用Tiles辅助开发”) 下面我们把关注的目光放在具体action里,看看struts是如何进行异常处理的 //ItemsCatalogAction.java package com.iplateau.jshop.action.ItemsCatalogAction import com.iplateau.jshop.business.ItemsCatalogMap; import com.iplateau.jshop.action.ItemsCatalogForm; import ***; public class ItemsCatalogAction extends BaseAction { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String flg=”error”; String act=request.getParameter(“act”); ItemsCatalogMap map=new ItemsCatalogMap(); ItemsCatalogForm thisform=( ItemsCatalogForm)form; // ItemsCatalogMap为具体的处理商品类别的类 if(act.equals(“create”)) { map.validateNameOfCatalog(thisform); map.create(thisform); flg=”success”; return mapping.findForward(flg); } else{ return mapping.findForward(flg); } } } 上便是一个简单的action,其中用act的具体内容来判断此时的action要处理的操作,如act为cteate的时候,处理的是商品类别的添加等等。 看了上边的代码,可以了解,在调用具体的业务类进行添加商品类别以前先要判断此时要添加的商品类别的合法性,如: 调用map.validateNameOfCatalog(thisform); 其中在ItemsCatalogMap定义的validateNameOfCatalog 方法抛出InvalidiItemsCatalogNameException。 下面让我们运行一下添加商品类别的例子,如果此时数据库中已经存在“牛奶制品”这个商品类别,而我们又要添加此类别的时候,程序如我们预想的一样转到error.jsp并且显示了我们要先是的错误信息:你要添加的商品类别已经存在,请添加新的类别! 其实就这么简单,我们的定制的异常在程序中并不需要用try/catch来捕获,一旦出现了我们已经定义的异常那么就会转到相应得页面,并且携带定制的信息。 还记得在struts先前的版本中我们的请求都是通过action的perform来处理,可是现在都要通过execute来处理,就其原因一个很重要的就是“成全”Exception Handling。为什么呢? 因为perform在声明的时候仅仅抛出IOException 和ServletException,这远远不能满足Exception Handling的要求,那么让我们看看execute是怎样的:它笼统的抛出Exception(所有异常的父类) 上 面的阐述只是一个引子,而且默认struts的异常是通过org.apache.struts.action. ExceptionHandler来处理的,你可以定义自己的处理方式,只要继承它并实现其中的execute方法,这个方法在ExceptionHandler的定义如下: public ActionForward execute (Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException 具体而且专业的分析Exception Handling的内容,请参看《Programming Jakarta Struts》第10章??这本书的电子版网上很多地方可以下载。 原文地址 http://tech.ccidnet.com/pub/article/c322_a74029_p1.html
|