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. Angularjs基础(五)

    AngularJS Select(选项框) AngularJS 可是使用数组或对象创建一个下拉列表选项.使用ng-options创建选项框 在AngularJS 中我们可以使用ng-option指令来 ...

  2. ETO的公开赛T2《宏聚变》 题解(BY 萌萌哒123456 )

    我们注意到这道题中最多有 $(n+q)$ 个数被加入,而每个数最多被删除一次,因此每次操作 $O(logn)$的复杂度是可以接受的. 我们对于$1..100000$之间每个数分别开一个set,维护这个 ...

  3. EF core Code First 简单的使用方法

    好吧,我又回来了,其实一直都想写一篇关于EF core 的文章去记录自己在开发时候遇到的问题. 为什么要使用EF框架呢,因为原始的ADO.NET需要编写大量的数据访问代码,所以使用EF会更方便.但是今 ...

  4. vue js 保留小数

    toFixed(number,fractionDigits ){ //number 保留小数数 //fractionDigits 保留小数位数 var times = Math.pow(10, fra ...

  5. tp3.2报错;syntax error, unexpected 'function' (T_FUNCTION), expecting identifier (T_STRING) or \\ (T_NS_SEPARATOR)

    出错原因:这个是php版本问题,laravel5.1的php版本要求是PHP >= 5.5.9,切换一下PHP版本就行.

  6. Python面向对象的类的操作

    import randomimport time class ElectronicCoupon(): def __init__(self): self.__ecid=time.strftime('%Y ...

  7. docker理论基础

    Namespaces 命名空间(namespaces)是 Linux 为我们提供的用于分离进程树.网络接口.挂载点以及进程间通信等资源的方法.在日常使用 Linux 或者 macOS 时,我们并没有运 ...

  8. 网站安全检测 漏洞检测 对thinkphp通杀漏洞利用与修复建议

    thinkphp在国内来说,很多站长以及平台都在使用这套开源的系统来建站,为什么会这么深受大家的喜欢,第一开源,便捷,高效,生成静态化html,第二框架性的易于开发php架构,很多第三方的插件以及第三 ...

  9. 2018 ccpc final I. Cockroaches

    I. Cockroaches time limit per test6. s memory limit per test256 MB inputstandard input outputstandar ...

  10. 高德API+Python解决租房问题(.NET版)

    源码地址:https://github.com/liguobao/58HouseSearch 在线地址:58公寓高德搜房(全国版):http://codelover.link:8080/ 周末闲着无事 ...