• 学习Struts框架系列(三):声明式异常处理


    Struts1.X的版本中加入了对异常的处理Exception Handler,有了它我们可以不使用try/catch捕获异常,一旦出现了我们已经定义的异常,那么就会转到相应的页面,并且携带异常信息,自动性增强。

    Struts框架提供了默认的异常处理org.apache.struts.action.ExceptionHandler,它的execute()方法负责处理异常,在需要实现自定义处理时重写该方法。可以在配置文件中定义由谁来处理Action类中掷出的某种异常。

      

    处理异常的流程

    struts的控制器负责捕获各种异常,包括控制器运行中本身抛出的异常,以及调用模型的业务方法时抛出的异常。

    当struts的控制器捕获到异常后,在异常处理代码块中,创建描述信息的actionMessage对象,并把它保存在特定范围(配置文件中的scope)。

    jsp中使用<html:errors/>标签,可以检索到特定范围内的actionMessages对象。



    通过这个完整的代码示例,你将知道如何使用ExceptionHandler统一处理异常

     

    struts配置文件

     

     

    <global-exceptions>
    <!-- 当遇到 type为java.lang.Exception异常时,使用com.bjsxt.oa.web.SystemExceptionHandler进行处理-->
    <exception
    key="errors.detail"
    type="java.lang.Exception"
    path="/common/exception.jsp"
    scope="request"
    handler="com.bjsxt.oa.web.SystemExceptionHandler"
    ></exception>
    </global-exceptions>


     

    key – 即这个异常所对应的错误提示消息文本的key,这个key的值,需要在资源属性文件中进行定义

    type – 即定义需要处理哪种类型的Exception

    path – 定义一旦出现异常,需要转向哪个页面来进行提示,如果不定义path属性,默认情况下,将使用Action配置中的input属性的值来作为转向的页面

    局部和全局

    handler -负责异常处理的类,缺省为org.apache.struts.action.Exceptionhandler.java如果做个性化的异常处理可以继承此类覆盖execute方法


    SystemExceptionHandler

     

    使用SystemExceptionHandler统一处理SystemException异常

    SystemExceptionHandler是自定义的ExceptionHandler类,重写了execute方法,实现自定义处理。


     

     

    importcom.bjsxt.oa.manager.SystemException;
     
    public classSystemExceptionHandler extends ExceptionHandler {
     
    //日志记录对象
    //commons-log类型接口,log4j实现
    privatestatic Log logger = LogFactory.getLog(SystemExceptionHandler.class);
     
    /**
     * 处理SystemException异常
     */
    @Override
    publicActionForward execute(
    Exceptionex,
    ExceptionConfigae,
    ActionMappingmapping,
    ActionFormformInstance,
    HttpServletRequestrequest,
    HttpServletResponseresponse) throws ServletException {
     
    //ExceptionConfig 和配置文件的exception标签信息对应
    //ActionMapping和请求的action标签信息对应
     
    //构造ActionForward对象
    ActionForwardforward = null;
    if(ae.getPath()!= null){
    forward= new ActionForward(ae.getPath());
    }else{
    forward= mapping.getInputForward();
    }
     
    logger.debug("出现异常",ex);
     
    //ex.printStackTrace();
     
    //只对SystemException异常进行处理
    //构造ActionMessage对象
    if(exinstanceof SystemException){
    SystemExceptionse = (SystemException)ex;
     
    //取出key值
    Stringkey = se.getKey();
     
    ActionMessageerror = null;
    if(key == null){
    error= new ActionMessage(ae.getKey(),se.getMessage());
    }else{
    if(se.getValues()!= null){
    error= new ActionMessage(key,se.getValues());
    }else{
    error= new ActionMessage(key);
    }
    }
     
    this.storeException(request,key, error, forward, ae.getScope());
     
    returnforward;
    }
     
     
    returnsuper.execute(ex, ae, mapping, formInstance, request, response);
    }
     
    }





     

    SystemException

    自定义异常类

     

     

    public classSystemException extends RuntimeException {
     
    //异常代码
    privateString key;
     
    privateObject[] values;
     
    publicSystemException() {
    super();
    }
     
     
    publicSystemException(String message) {
    super(message);
    }
     
    publicSystemException(Throwable throwable) {
    super(throwable);
    }
    publicSystemException(String message, Throwable throwable) {
    super(message,throwable);
    }
     
    publicSystemException(String message,String key){
    super(message);
    this.key= key;
    }
     
    publicSystemException(String message,String key,Object value){
    super(message);
    this.key= key;
    this.values= new Object[]{value};
    }
     
    publicSystemException(String message,String key,Object[] values){
    super(message);
    this.key= key;
    this.values= values;
    }
     
    publicString getKey() {
    returnkey;
    }
     
    publicObject[] getValues() {
    returnvalues;
    }
     
    }



    OrgManagerImpl

     

    在这里抛出异常,异常会一直抛到Action,直到被struts控制器捕获。

     

     

    publicvoid delOrg(int orgId) {
     
    Orgnizationorg = (Orgnization)getHibernateTemplate().load(Orgnization.class, orgId);
     
    //先判断是否存在子机构,如果存在子机构,则不允许删除
    if(org.getChildren().size()> 0){
    // 使用多种情况的异常信息:国际化、自定义
    thrownewSystemException("存在子机构,不允许删除","exception.org.del",org.getId());
    //        thrownew SystemException("存在子机构,不允许删除");
    }
     
    getHibernateTemplate().delete(
    org
    );
    }



     

     

    MessageResources.properties

    国际化资源文件


     

    exception.org.del=Can'tDel Orgnization,id is {0}!


    小结

    声明式异常,在代码中只进行抛异常就够了,捕获异常的事交给了ExceptionHandler类,省事多了。因为每一个异常类,对应的就需要有一个Handler类处理,所以这个异常类的粒度不能太细。

    和编程式异常相比,编程式异常就比较灵活了,在action中可以针对manager提供的异常情况再做处理,进而向页面显示出合理的友好的提示信息,但因为在action中作为异常的处理终点,导致action类会比较庞大而且代码可读性下降。 

    总之,处理异常的这两种方式,一个粒度粗些,一个粒度细些,酌情处理就是了。


  • 相关阅读:
    提取左公因子
    如何使用正则表达式构造相对应的ε-NFA
    DFA-NFA 简单介绍 怎么区分
    编译原理 短语 直接短语 定义
    编译原理 符号表为什么设计字符串表这样的结构?
    编译原理 词法分析
    paper 自动翻译论文软件推荐
    github 单个文件超过100M 解决办法 Git LFS 使用
    马哥博客作业第四周
    马哥博客作业第三周
  • 原文地址:https://www.cnblogs.com/james1207/p/3253882.html
Copyright © 2020-2023  润新知