Struts2的异常采用声明式异常捕捉,具体通过拦截器来实现。

在项目中,我们可以在Action中直接抛出异常,剩下的就交给Struts2的拦截器来处理了。当然,我们需要进行相关配置。

Struts2配置了默认的拦截器,来处理异常。在struts-default.xml中,可以找到配置。有了这个配置以后,我们在项目中就方便多了。

 <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>

在项目中,只需要使用exception-mapping标签来配置:

1)全局异常

适用对象:所有Action

<global-results >
<!-- 跳转到全局异常的页面 -->
<result name="global-error">/global-error.jsp</result>
</global-results> <global-exception-mappings>
<exception-mapping result="global-error" exception="com.struts2.ApplicationException"></exception-mapping>
</global-exception-mappings>

2)局部异常

使用对象:异常所在的Action

<!-- 局部异常,LoginAction -->
<action name="login" class="com.struts2.LoginAction"> <exception-mapping result="error" exception="com.struts2.ApplicationException"></exception-mapping>
<result>/success.jsp</result>
<result name="error">/error.jsp</result>
</action>

ApplicationException

Throwable是所有异常的根

Error是错误

Exception是异常,RuntimeException是运行中的异常。

除了Struts2自带的拦截器,我们还可以自定义拦截器,覆盖底层的拦截器,使得异常的捕捉更加灵活。

自定义拦截器的配置也十分方便。

<interceptors>
<!-- 声明拦截器 -->
<interceptor name="errorInterceptor" class="cn.itcast.util.ErrorInterceptor" />
<!-- 配置拦截器栈 -->
<interceptor-stack name="myErrorInterceptor">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="errorInterceptor" />
</interceptor-stack>
</interceptors>
<!-- 覆盖底层的拦截器栈 对包中的所有action都有效 -->
<default-interceptor-ref name="myErrorInterceptor"/> <global-results>
<result name="errorMsg">/errorMsg.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="errorMsg" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>

Struts2的“错误页”

经常使用ssh框架开发,会发现Struts2中各种报错页面的布局和显示信息很类似。这是因为Struts2提供了一个它自己的“错误页”,在org.apache.struts2.dispatcher包下。



<html>
<head>
<title>Struts Problem Report</title>
<style>
pre {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<h2>Struts Problem Report</h2>
<p>
Struts has detected an unhandled exception:
</p> <#assign msgs = [] />
<#list chain as ex>
<#if ex.message??>
<#assign msgs = [ex.message] + msgs/>
</#if>
</#list>
<#assign rootex = exception/>
<#list chain as ex>
<#if (ex.location?? && (ex.location != unknown))>
<#assign rootloc = ex.location/>
<#assign rootex = ex/>
<#else>
<#assign tmploc = locator.getLocation(ex) />
<#if (tmploc != unknown)>
<#assign rootloc = tmploc/>
<#assign rootex = ex/>
</#if>
</#if>
</#list> <div id="exception-info">
<table>
<tr>
<td><strong>Messages</strong>:</td>
<td>
<#if (msgs?size > 1)>
<ol>
<#list msgs as msg>
<#if (msg?is_method)>
<li>${msg[0]}</li>
<#else>
<li>${msg}</li>
</#if>
</#list>
</ol>
<#elseif (msgs?size == 1)>
<#if (msgs[0]?is_method)>
<li>${msgs[0][0]}</li>
<#else>
<li>${msgs[0]}</li>
</#if>
</#if>
</td>
</tr>
<#if rootloc??>
<tr>
<td><strong>File</strong>:</td>
<td>${rootloc.URI}</td>
</tr>
<tr>
<td><strong>Line number</strong>:</td>
<td>${rootloc.lineNumber}</td>
</tr>
<#if (rootloc.columnNumber >= 0)>
<tr>
<td><strong>Column number</strong>:</td>
<td>${rootloc.columnNumber}</td>
</tr>
</#if>
</#if> </table>
</div> <#if rootloc??>
<#assign snippet = rootloc.getSnippet(2) />
<#if (snippet?size > 0)>
<div id="snippet">
<hr /> <#list snippet as line>
<#if (line_index == 2)>
<#if (rootloc.columnNumber >= 3)>
<pre style="background:yellow">${(line[0..(rootloc.columnNumber-3)]?html)}<span style="background:red">${(line[(rootloc.columnNumber-2)]?html)}</span><#if ((rootloc.columnNumber)<line.length())>${(line[(rootloc.columnNumber-1)..]?html)}</#if></pre>
<#else>
<pre style="background:yellow">${line?html}</pre>
</#if>
<#else>
<pre>${line?html}</pre>
</#if>
</#list>
</div>
</#if>
</#if> <div id="stacktraces">
<hr />
<h3>Stacktraces</h3>
<#list chain as ex>
<div class="stacktrace" style="padding-left: ${ex_index * 2}em">
<strong>${ex}</strong>
<div>
<pre>
<#list ex.stackTrace as frame>
${frame}
</#list>
</pre>
</div>
</div>
</#list>
</div> <div class="footer">
<hr />
<p>
You are seeing this page because development mode is enabled. Development mode, or devMode, enables extra
debugging behaviors and reports to assist developers. To disable this mode, set:
<pre>
struts.devMode=false
</pre>
in your <code>WEB-INF/classes/struts.properties</code> file.
</p>
</div>
</body>
</html>

SSH答疑解惑系列(三)——Struts2的异常处理的更多相关文章

  1. SSH答疑解惑系列(一)——spring容器是如何启动的

    SSH框架十分受欢迎,其中有一个原因就是spring可以和Struts2框架无缝整合.在使用spring时,无需手动创建web容器,而是通过配置文件声明式创建spring容器. 在web应用中,创建s ...

  2. SSH答疑解惑系列(二)——java.lang.reflect.InvocationTargetException异常

    在项目中遇到了invocationTargetException的问题,在这里跟大家分享一下. 报错信息如下: 使用反射时,比如执行invoke方法,如果被反射执行的方法体抛出了Exception,这 ...

  3. (Struts2学习系列三)Struts2动态方法调用:通配符方式

    更改src/struts2.xml的代码: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...

  4. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  5. 《浅谈磁盘控制器驱动》,磁盘控制器驱动答疑解惑![2012.1.29完结]by skyfree

    <浅谈磁盘控制器驱动>,磁盘控制器驱动答疑解惑![2012.1.29完结]  https://www.itiankong.net/thread-178655-1-1.html Skyfre ...

  6. Ansible Tower系列 三(使用tower执行一个任务)【转】

    创建playbook Tower playbook 项目默认存在 /var/lib/awx/projects/ su - awx cd projects/ mkdir ansible-for-devo ...

  7. 【struts2】Struts2的异常处理

    在Action中execute方法声明为:public String execute() throws Exception,这样,Action可以抛出任何Exception. 1)自己实现异常处理 我 ...

  8. S5PV210开发系列三_简易Bootloader的实现

    S5PV210开发系列三 简易Bootloader的实现 象棋小子          1048272975 Bootloader是嵌入式系统上电后第一段运行的代码.对于功能简单的处理器,可能并没有Bo ...

  9. SSH初体验系列--Hibernate--2--crud操作

    Ok,今天比较详细的学习一下hibernate的C(create).R(read).U(update).D(delete) 相关api... 前言 Session: 是Hibernate持久化操作的基 ...

随机推荐

  1. c#常用数据库封装再次升级

    c#封装的几类数据库操作: 1.sqilte 2.berkeleydb 3.一般数据库 4.redis 包含其他项目: 1.序列化 2.通信 3.自定义数据库连接池 再次升级内容: 1.新增redis ...

  2. POJ 1066--Treasure Hunt(判断线段相交)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7857   Accepted: 3247 Des ...

  3. poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)

    /** problem: http://poj.org/problem?id=3177 tarjan blog: https://blog.csdn.net/reverie_mjp/article/d ...

  4. NC使用技巧

    1. NC 1.1概述 1.1.1 优点: 1)网络工具中的瑞士军刀 2)侦听模式/传输模式. 3)可代替telnet获取banner信息. 4)传输文件/目录. 5)传输文本信息. 6)加密传输文件 ...

  5. springmvc重定向请求。

    SpringMVC重定向传参数的实现(来自网友) 验证了我说的,从model层中拿来的数据,不管什么类型,都是通过隐含模型,中转,放入request中的.除非你特意把这些数据放到session域中. ...

  6. HTML自定义Checkbox框背景色

    input[type=checkbox]{ margin-right:5px; width:13px; height:13px; }input[type=checkbox]:after { width ...

  7. 微信小程序播放视频

    <view class="section tc"> <video id="myVideo" src="http://wxsnsdy. ...

  8. Hadoop(17)-MapReduce框架原理-MapReduce流程,Shuffle机制,Partition分区

    MapReduce工作流程 1.准备待处理文件 2.job提交前生成一个处理规划 3.将切片信息job.split,配置信息job.xml和我们自己写的jar包交给yarn 4.yarn根据切片规划计 ...

  9. 神级编辑器 sublime text 和 神级插件 emmet

    h1{foo}和a[href=#] 生成如下代码 <h1>foo</h1>  <a href="#"></a> 嵌套的使用 > ...

  10. pyc是个什么鬼?

    1.Python是一门解释型语音? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释型语音,我就这样一直相信下去,知道发现了*.pyc文件的存在.如果是解释型语音,那 ...