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. LeetCode 简单 - 最大子序和(53)

    采用动态规划方法O(n) 设sum[i]为以第i个元素结尾且和最大的连续子数组.假设对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且和最大的连续子数组实际上,要么是以 ...

  2. Linux性能监控工具 gtop

    给大家介绍一款性能监控工具,个人对比界面比top美观,常用指标比较清晰毕竟top上的指标不是每个人都能熟悉,也不是所有指标参数都需要看,对于新手也不便查找,好了说的再多先上图大家参观一下. 1.安装需 ...

  3. vue 路由对象(常用的)

    路由对象 在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,并且当路由切换时,路由对象会被更新. 路由对象暴露了以下属性: $route.path ...

  4. Sencha Visual Studio(IDE插件)

    Sencha Visual Studio(IDE插件) 首先从官网上下载Visual Studio插件,注意不是VSCode编辑器,下载完后安装打开Visual Studio提示你去注册,输入你的se ...

  5. python 装饰器 (多个装饰器装饰一个函数---装饰器前套一个函数)

    #带参数的装饰器 #500个函数 # import time # FLAGE = False # def timmer_out(flag): # def timmer(func): # def inn ...

  6. ecshop 全系列版本网站漏洞 远程代码执行sql注入漏洞

    ecshop漏洞于2018年9月12日被某安全组织披露爆出,该漏洞受影响范围较广,ecshop2.73版本以及目前最新的3.0.3.6.4.0版本都受此次ecshop漏洞的影响,主要漏洞是利用远程代码 ...

  7. Excel学习路径总结

    本片涉及从入门到Excel的各个方向,包含众多资料和自己学习的心得,希望您可以仔细阅之:   入门篇: 无论是软件,还是编程,最好的入门就是通过看视频来学习,视频优点为很容易看清楚,手把手教授,不容易 ...

  8. BootCDNApi使用记录

    通过API获取BootCDN所加速的所有前端开源库的基本信息和文件列表 API 将一下API链接中的.min字样去掉后,获取到的JSON格式的返回信息是经过良好的格式化的,便于查看. 所有开源库简要信 ...

  9. PATA1034题解

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624 参考:算法笔记(胡凡)10.3.1 # ...

  10. mybatis-generator自定义注释生成

    最近做的项目发现没有中文注释,故查找资料,特此记录. 本文所用的是基于mybatis-generator 1.3.2版本来完成的. mybatis-generator 自动生成的代码注释是很反人类的, ...