SSH答疑解惑系列(三)——Struts2的异常处理
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的异常处理的更多相关文章
- SSH答疑解惑系列(一)——spring容器是如何启动的
SSH框架十分受欢迎,其中有一个原因就是spring可以和Struts2框架无缝整合.在使用spring时,无需手动创建web容器,而是通过配置文件声明式创建spring容器. 在web应用中,创建s ...
- SSH答疑解惑系列(二)——java.lang.reflect.InvocationTargetException异常
在项目中遇到了invocationTargetException的问题,在这里跟大家分享一下. 报错信息如下: 使用反射时,比如执行invoke方法,如果被反射执行的方法体抛出了Exception,这 ...
- (Struts2学习系列三)Struts2动态方法调用:通配符方式
更改src/struts2.xml的代码: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- 《浅谈磁盘控制器驱动》,磁盘控制器驱动答疑解惑![2012.1.29完结]by skyfree
<浅谈磁盘控制器驱动>,磁盘控制器驱动答疑解惑![2012.1.29完结] https://www.itiankong.net/thread-178655-1-1.html Skyfre ...
- Ansible Tower系列 三(使用tower执行一个任务)【转】
创建playbook Tower playbook 项目默认存在 /var/lib/awx/projects/ su - awx cd projects/ mkdir ansible-for-devo ...
- 【struts2】Struts2的异常处理
在Action中execute方法声明为:public String execute() throws Exception,这样,Action可以抛出任何Exception. 1)自己实现异常处理 我 ...
- S5PV210开发系列三_简易Bootloader的实现
S5PV210开发系列三 简易Bootloader的实现 象棋小子 1048272975 Bootloader是嵌入式系统上电后第一段运行的代码.对于功能简单的处理器,可能并没有Bo ...
- SSH初体验系列--Hibernate--2--crud操作
Ok,今天比较详细的学习一下hibernate的C(create).R(read).U(update).D(delete) 相关api... 前言 Session: 是Hibernate持久化操作的基 ...
随机推荐
- vue和react总结
一.总结一下Vue和React的区别 相同点: 1.都支持服务器端渲染 2.都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent ...
- vs2017中的scanf_s
在visual studio 2017中格式化输入函数不同于其他c/c++编译器使用scanf,而是使用scanf_s. scanf_s相比较于scanf来说更安全,因为使用scanf_s函数需要有一 ...
- ABAP术语-Purchase Order
Purchase Order 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/07/1094717.html Request or instr ...
- shell 输出带颜色字体
输出特效格式控制:\033[0m 关闭所有属性 \033[1m 设置高亮度 \03[4m 下划线 \033[5m 闪烁 \033[7m 反显 \033[8m 消隐 \ ...
- collections模块的使用
1. Counter counter是collections中的一个模块, 它能够统计出字符串/文本中的每一个元素出现的次数, 并可以对结果进行进一步的处理. 使用方法 传入: 字符串 默认返回: C ...
- Vue2+VueRouter2+webpack+vue-cil构建完整项目实例(附:详细步骤截图)
引用1:https://segmentfault.com/a/1190000008557578 引用2:https://blog.csdn.net/wulala_hei/article/details ...
- tomcat+nginx+keepalived的配置
tomcat+nginx+keepalived的配置 1.在官网上下载Tomcat 2.将压缩包解压,并且移动到/opt/data/的目录下. .tar.gz /opt/data/ 3.进入到Tomc ...
- POJ1659 可图性判定
Frogs' Neighborhood Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 10660 Accepted: 4 ...
- (数据科学学习手札03)Python与R在随机数生成上的异同
随机数的使用是很多算法的关键步骤,例如蒙特卡洛法.遗传算法中的轮盘赌法的过程,因此对于任意一种语言,掌握其各类型随机数生成的方法至关重要,Python与R在随机数底层生成上都依靠梅森旋转(twiste ...
- LeetCode算法1—— 两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...