`

Struts2的声明式异常处理

    博客分类:
  • SSH
 
阅读更多

在struts2应用程序中你还在使用try catch语句来捕获异常么?如果是这样的,那你OUT啦!struts2支持声明式异常处理,可以再Action中直接抛出异常而交给struts2来处理,当然需要我们在xml文件中配置,由于抛出同样的异常的处理方法通常都一样,所以如果能在xml中配置全局异常,将会使得开发便捷性大大提高。

以前的异常捕获可能是这样的:

/**
 * 执行更新
 
 * @return
 */
public String update() {
    Article article = new Article();
    article.setContent(content);
    article.setTitle(title);
    article.setId(id);
    try {
        articleService.update(article);
        return SUCCESS;
    } catch (SQLException e) {
        e.printStackTrace();
        return ERROR;
    } catch (InvalidInputException e) {
        e.printStackTrace();
        System.out.println("输入非法");
        return ERROR;
    }
}

这种方式是完全的手动处理异常,一来不够简洁明快,而且还不容易维护,毕竟如果修改了这些代码都需要再次编译。

采用struts2的声明式异常处理就会简单很多了。

首先,上面的代码的try catch 就可以全都不要了,但是,当然,得新加throw语句抛出异常:

/**
 * 执行更新
 
 * @return
 * @throws InvalidInputException
 * @throws SQLException
 */
public String update() throws SQLException, InvalidInputException {
    Article article = new Article();
    article.setContent(content);
    article.setTitle(title);
    article.setId(id);
    articleService.update(article);
    return SUCCESS;
}

代码清晰了很多,不是么?

捕获异常的任务则交给xml配置文件了,配置文件还是比较容易理解的:

<package name="wow" extends="struts-default">
	<global-results>
		<result name="sql">/internal_Error.jsp</result>
		<result name="invalidinput">/invalid_Input.jsp</result>
		<result name="naming">/internal_Error.jsp</result>
	</global-results>
	<global-exception-mappings>
		<exception-mapping result="sql" exception="java.sql.SQLException"></exception-mapping>
		<exception-mapping result="invalidinput"
			exception="cn.codeplus.exception.InvalidInputException"></exception-mapping>
		<exception-mapping result="naming"
			exception="javax.naming.NamingException"></exception-mapping>
	</global-exception-mappings>
	<action name="*_*" class="cn.codeplus.action.{2}Action" method="{1}">
		<result name="success">/{1}_{2}_success.jsp</result>
		<result name="error">/{1}_{2}_error.jsp</result>
		<!--<exception-mapping result="sql" exception="java.sql.SQLException"></exception-mapping>-->
	</action>
</package>

用于异常处理的<exception-mapping>标签可以配置在Action中,也可以配置在<global-exception-mappings>,顾名思义<global-exception-mappings>就是全局异常,当然执行Action的时候发生异常时,如果在Action中没有捕获异常而是抛出异常的话,struts2会首先在正在执行的Action中查找<exception-mapping>,寻找对应的Exception进行处理,如果找不到,才会去<global-exception-mappings>去寻找对应的Exception处理,如果还是找不到的话,就只好抛出异常了。

下面说说异常处理:

<exception-mapping result="sql" exception="java.sql.SQLException"></exception-mapping>

上面代码说明,当捕获java.sql.SQLException时候,去寻找对应的result为sql的视图返回,即<global-result>中name为sql的result去返回internal_Error.jsp。当然如果<exception-mapping>配置在action中的话,则会首先去action的result搜寻返回视图,失败了才会去搜寻<global-result>。

在我们编写上面的xml配置的时候可能会遇到如下错误:

这个是因为,我们xml配置文件各个标签<action>、<global-result>、<global-exception-mapping>的顺序不对,调整一下标签的顺序,符合黄色的提示语即可。

最后,我们说说视图层怎样获取异常信息,invalid_Input.jsp文件是这样的:

...
<%@taglib prefix="s" uri="/struts-tags"%>
...
<body>
	<jsp:include page="nav.jsp"></jsp:include>
	<div>
		抱歉,服务器内部错误。
	</div>
	<div>
		<s:property value="exception.message"/>
	</div>
	<s:debug></s:debug>
</body>
...
<s:property value="exception.message"/>表示从valuestack中获取错误信息,显示在前台页面上。当然,我们也可以选择更人性化得处理方案,比如说,放个失望的表情,写上“抱歉,服务器内部错误,您可以发邮件给我们提示此错误,xxxx@xxxx.com”等等;
经测试,当发生SQLException的时候,页面信息如下:

好了,很高兴来到园子,嘿嘿,希望这篇文章对大家有用

 

 

 

===================================================

Struts2的异常处理机制:

任何成熟的MVC框架都应该提供成就的异常处理机制。Strut2也不例外。Struts2提供了一种声明式的异常处理方式。Struts2也是通过配置的拦截器来实现异常处理机制的。

Struts2的异常处理机制通过在struts.xml文件中配置﹤exception-mapping …﹥元素完成的,配置该元素时,需要指定两个属性:

exception:此属性指定该异常映射所设置的异常类型。

result:此属性指定Action出现该异常时,系统转入result属性所指向的结果。


  异常映射也分为两种:

局部异常映射:﹤exception-mapping…﹥元素作为﹤action…﹥元素的子元素配置。

 全局异常映射:﹤exception-mapping…﹥元素作为﹤global-exception-mappings﹥元素的子元素配置。


   输出异常信息:

使用Struts2的标签来输出异常信息:

 ﹤s:property value="exception.message"/﹥:输出异常对象本身。

﹤s:property value="exceptionStack"/﹥: 输出异常堆栈信息。

 

 

 

利用struts2的异常处理机制和拦截器机制可以很方便的实现异常处理功能,你不再需要在Action中捕获异常,并抛出相关的异常了,这些都交给拦截器来帮你做了。

 

 

1.  在 struts.xml 文件中,声明全局异常映射,以及对应的全局异常转发如下所示:

﹤global-results﹥

﹤result name="error"﹥/admin/error/ErrDisplay.ftl﹤/result﹥

﹤/global-results﹥

﹤global-exception-mappings﹥

﹤exception-mapping result="error" exception="com.orizone.hbmobile.hbcm.struts.BusinessException"﹥﹤/exception-mapping﹥

﹤/global-exception-mappings﹥

 

BusinessException  是异常处理类,代码如下所示:

 

public class BusinessException extends RuntimeException

{

 

    private static final long serialVersionUID = 0xc1a865c45ffdc5f9L;

   

    public BusinessException(String frdMessage)

    {

        super(createFriendlyErrMsg(frdMessage));

     

    }

 

    public BusinessException(Throwable throwable)

    {

        super(throwable);

    }

 

    public BusinessException(Throwable throwable, String frdMessage)

    {

        super(throwable);

      

    }

   

   

private static String createFriendlyErrMsg(String msgBody){

String prefixStr = "抱歉,";

String suffixStr = " 请稍后再试或与管理员联系!";

 

StringBuffer friendlyErrMsg = new StringBuffer("");

 

friendlyErrMsg.append(prefixStr);

friendlyErrMsg.append(msgBody);

friendlyErrMsg.append(suffixStr);

 

return friendlyErrMsg.toString();

}

}

 

 

2.  /admin/error/ErrDisplay.ftl 页面

这个页面很简单:

﹤body﹥

 ﹤h2﹥

         出现异常啦

 ﹤/h2﹥

 ﹤hr/﹥

   ﹤h3 style="color:red"﹥

   ﹤!-- 获得异常对象 --﹥

   

    ${exception.message?default("")}

    ﹤/h3﹥

    ﹤br/﹥

    ﹤!-- 异常堆栈信息(开发人员用) --﹥

    ﹤div style="display:none;"﹥

       ${exceptionStack?default("")}

    ﹤/div﹥

﹤/body﹥

﹤body﹥

 ﹤h2﹥

         出现异常啦

 ﹤/h2﹥

 ﹤hr/﹥

   ﹤h3 style="color:red"﹥

   ﹤!-- 获得异常对象 --﹥

   

    ${exception.message?default("")}

    ﹤/h3﹥

    ﹤br/﹥

    ﹤!-- 异常堆栈信息(开发人员用) --﹥

    ﹤div style="display:none;"﹥

       ${exceptionStack?default("")}

    ﹤/div﹥

﹤/body﹥

 

3.  在拦截器中,捕获常见的异常,并以友好异常信息抛出,相关代码如下所示:

public String intercept(ActionInvocation invocation) throws Exception

{

before(invocation);

String result = "";

 

try{

result = invocation.invoke();

}catch(DataAccessException ex){

throw new BusinessException("数据库操作失败!");

}catch(NullPointerException ex){

throw new BusinessException("调用了未经初始化的对象或者是不存在的对象!");

}catch(IOException ex){

throw new BusinessException("IO异常!");

}catch(ClassNotFoundException ex){

throw new BusinessException("指定的类不存在!");

}catch(ArithmeticException ex){

throw new BusinessException("数学运算异常!");

}catch(ArrayIndexOutOfBoundsException ex){

throw new BusinessException("数组下标越界!");

}catch(IllegalArgumentException ex){

throw new BusinessException("方法的参数错误!");

}catch(ClassCastException ex){

throw new BusinessException("类型强制转换错误!");

}catch(SecurityException ex){

throw new BusinessException("违背安全原则异常!");

}catch(SQLException ex){

throw new BusinessException("操作数据库异常!");

}catch(NoSuchMethodError ex){

throw new BusinessException("方法末找到异常!");

}catch(InternalError ex){

throw new BusinessException("Java虚拟机发生了内部错误");

}catch(Exception ex){

throw new BusinessException("程序内部错误,操作失败!");

}

 

after(invocation, result);

return result;

}

struts2做异常处理还是比较方便的了。

分享到:
评论

相关推荐

    Struts 声明式异常处理和个性化异常处理

    NULL 博文链接:https://xace.iteye.com/blog/416561

    Struts2 学习笔记

    07 声明式异常处理 33 08 国际化 35 一、 国际化资源文件 35 二、 Java国际化 35 三、 Struts2国际化 35 1、 Action级别 35 2、 Package级别 36 3、 Application级别 36 四、 资源文件中的参数处理 37 五、 国际化-...

    Struts2中异常处理机制分析

    主要介绍了Struts2中异常处理机制分析,涉及到了声明式异常捕捉的相关内容,以及两种异常映射的分析,需要的朋友可以参考下。

    Struts2帮助```````

    07 声明式异常处理 33 08 国际化 35 一、 国际化资源文件 35 二、 Java国际化 35 三、 Struts2国际化 35 1、 Action级别 35 2、 Package级别 36 3、 Application级别 36 四、 资源文件中的参数处理 37 五、 国际化-...

    Spring3.x_Struts2.x_Hibernate3.x整合之声明式事务配置

    事务声明在Dao中,但是通常都会在Service中来处理多个业务逻辑的关系,如:删除,更新等,此时如果在执行了一个步骤之后抛出抛出异常就会导致数据部完整,所以事务不应该在Dao中处理,而应该在Service中处理,这也是...

    Web表现层框架 MyFrame

    用标准XML配置文件来控制转发流程,支持国际化(有国际化标签),支持声明式异常处理,框架中用到多种设计模式(单例模式、抽象工厂模式、代理模式、门面模式等等)。基本控制流程类似Struts,但业务控制类(Action)不...

    低清版 大型门户网站是这样炼成的.pdf

    2.1.9 struts 2的异常处理 52 2.2 struts 2配置精要 54 2.2.1 web.xml中struts 2的配置实现 54 2.2.2 struts 2属性配置文件struts.properties详解 55 2.2.3 struts 2核心配置文件struts.xml详解 57 2.3 struts ...

    Spring_Hibernate集成

    1、声明式事务配置 * 配置SessionFactory * 配置事务管理器 * 事务的传播特性 * 那些类那些方法使用事务 2、编写业务逻辑方法 * 继承HibernateDaoSupport类,使用HibernateTemplate来持久化,...

    Java Web程序设计教程

    13.3.3声明式事务处理 267 13.3.4标注式事务处理 268 13.4项目实战——公司人事管理 269 本章小结 276 课后练习 276 第14章spring与struts2、hibernate框架的整合基础 277 14.1spring与struts2的整合方式 277...

    Spring2.5和Hibernate3集成--学习spring aop ioc

    * 在编写业务逻辑方法时,最好将异常一直往上抛出,由表示层处理(Struts) * spring的事务管理需要添加到业务逻辑上(事务边界的定义),不要回到Dao上 技术提示: 在编写经下代码时: *" propagation=...

    Spring in Action(第二版 中文高清版).part2

    6.4 声明式事务 6.4.1 定义事务参数 6.4.2 代理事务 6.4.3 在Spring 2.0里声明事务 6.4.4 定义注释驱动事务 6.5 小结 第7章 保护Spring 7.1 Spring Security介绍 7.2 验证用户身份 7.2.1 配置Provider ...

    Spring in Action(第2版)中文版

    6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2...

    Spring in Action(第二版 中文高清版).part1

    6.4 声明式事务 6.4.1 定义事务参数 6.4.2 代理事务 6.4.3 在Spring 2.0里声明事务 6.4.4 定义注释驱动事务 6.5 小结 第7章 保护Spring 7.1 Spring Security介绍 7.2 验证用户身份 7.2.1 配置Provider ...

    spring.doc

    5.1.8声明式事务管理 116 5.1.8.1Spring的事务管理器 117 5.1.8.2Spring事务的传播属性 117 5.1.8.3Spring事务的隔离级别 117 拓展: 118 5.1.8.4以XML配置的 形式 119 拓展: 120 5.1.8.5以注解方式配置 125 拓展:...

    java面试题

    答:声明式的事务管理主要是将在进行对数据库中数据的添加或者修改时需要执行事务管理,主要是为了避免在执行添加或修改的时候添加或修改不完全正确,导致数据丢失。spring使用AOP面向切面的思想进行事务管理的。 ...

    spring in action英文版

     5.3 声明式事务  5.3.1 理解事务属性  5.3.2 声明一个简单的事务策略  5.4 通过方法名声明事务  5.4.1 使用NameMatchTransactionAttributeSource  5.4.2 名称匹配事务的捷径  5.5 用元数据声明...

    Java语言基础下载

    Struts如何实现Model 2, MVC 639 Struts 控制流 639 Struts framework的工作原理和组件 642 Struts ActionServlet控制器对象 642 Struts Action Classes 642 搞定Action对象 643 处理异常 643 Action的分类 643 ...

    spring 帮助文档(chm格式)

    Spring为 已建立的企业级应用提供了一个轻量级的解决方案,这个方案包括声明式事务管理, 通过RMI或webservices远程访问业务逻辑,mail支持工具以及数据库持久化的多种选择。 Spring还提供了一个MVC应用框架,可以...

Global site tag (gtag.js) - Google Analytics