Struts2学习笔记(七) 结果(Result)(下)
异常映射
我们知道在action的execute方法签名中定义了可以抛出任何类型的异常。至于这个异常抛给了谁,那当然是struts2框架了,如果我们没有设置响应的策略,那么struts2也不会对异常进行处理,又直接抛给web容器了。
如果我们需要Aaction在发生异常时跳转到指定的提示页面,那么我们当然可以在action中使用try..catch语句来返回不同的结果,但是Struts2为我们提供了更加方便的方式,那就是异常映射。我们只需要在配置文件中进行一些配置,就可以省去action中的try。。catch语句块。配置的方式就是在<action>元素中使用<exception-mapping>元素,可以指定在动作方法抛出指定异常时要执行那个result。
<action name="*User" class="action.UserAction" method="{1}">
<result name="input">/input.jsp</result>
<result name="success">success.jsp</result>
<result name="error">/error.jsp</result>
<exception-mapping result="error" exception="java.lan.ArithmeticException"></exception-mapping>
</action>
其中exception属性用于指出捕获指定的异常类型,result属性用于指出在捕获到该异常时需要呈现的result。
异常捕获通过exception拦截器来实现,该拦截器位于defaultStack拦截器栈的最顶端,因此能够不会整个调用过程中的异常,exception拦截器对应的实现类为:
com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor查看其源码:
public String intercept(ActionInvocation invocation) throws Exception { String result; try { result = invocation.invoke(); } catch (Exception e) { if (isLogEnabled()) { handleLogging(e); } List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); String mappedResult = this.findResultFromExceptions(exceptionMappings, e); if (mappedResult != null) { result = mappedResult; publishException(invocation, new ExceptionHolder(e)); } else { throw e; } } return result; } protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) { invocation.getStack().push(exceptionHolder); }
可以看到在exception拦截器中使用了try。。catch来捕获整个执行过程中的异常,如果执行过程中没有抛出异常,那么就将Action的执行结果正常返回,如果执行过程中出现了异常,那么就会查找与抛出的异常类型最接近的异常映射,并且将返回在在异常映射中配置的Result。
并且拦截器会将捕获到的异常包装成ExceptionHolder对象并将其压入valueSack。我们在看一下ExceptionHolder类的源码:
public class ExceptionHolder implements Serializable { private Exception exception; /** * Holds the given exception * * @param exception the exception to hold. */ public ExceptionHolder(Exception exception) { this.exception = exception; } /** * Gets the holded exception * * @return the holded exception */ public Exception getException() { return this.exception; } /** * Gets the holded exception stacktrace using {@link Exception#printStackTrace()}. * * @return stacktrace */ public String getExceptionStack() { String exceptionStack = null; if (getException() != null) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); try { getException().printStackTrace(pw); exceptionStack = sw.toString(); } finally { try { sw.close(); pw.close(); } catch (IOException e) { // ignore } } } return exceptionStack; } }
可以看到,在该类中将exception的trackStack转换成字符串存放在exceptionStack变量中。在struts2中要想使用OGNL调用Action类的某个属性,那么我们必须保证该属性有对应的get方法。那么实际上的调用全部是通过调用get方法来获取的,至于到底Action中是否存在对应的变量以及变量的名字是否和get方法对应其实并不影响,真正起作用的只是get方法。那么在这个ExceptionHolder类中有两个get方法,一个是getException,另一个是getExceptionStack,那么也就是说我们在使用OGNL调用该类的属性时,相当于存在两个属性:exception和exceptionStack。因为这个ExceptionHolder对象已经被放入了valueStack的顶部,也就是说,我们可以在我们配置的异常结果页面通过OGNL来访问这两个属性的内容:
<s:propertyvalue="%{exception.message}"/>
<s:propertyvalue="%{exceptionStack}"/>
PreResultListenner
不管处于什么目的,有时候我们需要在Action方法执行完毕,但是在执行Result之前能够做点什么。那么怎么实现这个功能呢?这时PreResultListener就派上用场了。一看它的名字就知道它是一个Listenner,那么它监听的事件就是Action方法执行完毕,将要执行Result。具体这个时间我们并不需要关注,struts2会自动分发这个事件,并触发我们的监听器。我们要做的就是实现这个Listenner,并把它注册到Action上。
首先我们需要实现PreResultLisenner这个接口:
public class MyPreResultListennerImpl implements PreResultListener { public void beforeResult(ActionInvocation invocation, String resultCode) { System.out.println("正在执行"+resultCode+"结果执行之前的操作..."); } }
我们的实现类所做的操作就打印一句话,用于我们判断执行的先后顺序。
然后我们在Result视图中也打印一句话:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>PreResultListenner Demo Result</title>
</head>
<body>
<%
System.out.println("结果页面已经被执行....");
%>
</body>
</html>
我们在Action的excute方法中对我们的Listenner进行注册:
public class HelloWorld extends ActionSupport { private String userName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String execute() throws Exception { ActionContext.getContext().getActionInvocation().addPreResultListener( new MyPreResultListennerImpl()); return "success"; } }
在struts.xml配置helloworld动作,并配置相应的Result,然后我们在浏览器中访问一下helloworld动作,页面执行完毕之后查看控制台的输出:
正在执行success结果执行之前的操作...
结果页面已经被执行....
表明在执行Result之前确实先执行了我们的Listenner。
自定义Result
自定义Result就是我们自己开发Result,不实用Struts2内建的Result Type,实际使用中我们几乎不会用到自定义Result,strut2内建的Result Type已经够我们使用了。这里就当时简单的了解一下吧。
要实现自定义Result,其步骤如下:
(1) 定义一个类,实现com.opensymphony.xwork2.Result接口
(2) 在struts.xml中,在<package>元素中使用<result-types>元素声明我们的Result Type
(3) 在Action中的<result>元素中将type属性指定为我们在(2)中声明的Result Type
下面动手做一个简单的实例:
public class MyResult implements Result { public void execute(ActionInvocation invocation) throws Exception { System.out.println("要执行的reuslt为:" + invocation.getResultCode()); } }
这里我只是简单的打印出一句话,当然,实际要实现一个Result需要做的事情很多,有兴趣的可以参看struts2内建的Result Type的实现。
struts.xml
<package name="default" namespace="/" extends="struts-default">
<result-types>
<result-type name="myresult"class="action.MyResult"></result-type>
</result-types>
<action name="hello" class="action.HelloWorld">
<result name="input">/input.jsp</result>
<result name="success" type="myresult">/success.jsp</result>
</action>
</package>
我在浏览器中测试,由于我们result实现中没有任何执行输出到浏览器的功能,因此浏览中无任何输出,查看控制台,输出如下:
要执行的reuslt为:success
到这里,我们自定义的Result就完成了。从这个例子中我们也可以看出,要实现自定义的Result其实不难,难的就是我们怎么去呈现这些数据,那么我们就必须使用一种视图呈现技术,实际Result也就是对视图呈现技术的一中包装(或者说调用吧)。
转载于:https://www.cnblogs.com/JPAORM/archive/2012/05/19/2509741.html
Struts2学习笔记(七) 结果(Result)(下)相关推荐
- 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码
吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...
- ROS学习笔记七:使用rqt_console和roslaunch
ROS学习笔记七:使用rqt_console和roslaunch 本节主要介绍在调试时使用的rqt_console和rqt_logger_level,以及一次性打开多个节点的工具roslaunch. ...
- 【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练
[K210]K210学习笔记七--使用K210拍摄照片并在MaixHub上进行训练 前言 K210准备工作 K210如何拍摄照片 准备工作 拍摄相关代码定义 用K210拍摄到的照片在MaixHub平台 ...
- window的dos命令学习笔记 七
文章目录 一.dos历史学习笔记(后期整合到这里,我想能学到这里的应该不多了,嘿嘿,加油) 二.执行状态返回值(`%errorlevel%`,和shell中`$?`相似): 三.视窗 1.color ...
- ESP32学习笔记(七) 复位和时钟
ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...
- 逆向脱壳破解分析基础学习笔记七 堆栈图(重点)
本文为本人 大神论坛 逆向破解脱壳学习笔记之一,为本人对以往所学的回顾和总结,可能会有谬误之处,欢迎大家指出. 陆续将不断有笔记放出,希望能对想要入门的萌新有所帮助,一起进步 堆栈图 首先给定一段反汇 ...
- OpenCV学习笔记(七)——图像梯度及边缘检测
图像梯度计算的是图像变化的速度.对于图像的边缘部分,其灰度值变化较大,梯度值也较大:相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小.一般情况下,图像梯度计算的是图像的边缘信息. ...
- 13、《Libevent中文帮助文档》学习笔记13:Linux下集成、运行libevent
Linux下编译libevent的指导可以参考<4.<Libevent中文帮助文档>学习笔记4:Linux下编译libevent>,完成编译.安装,生成so库后,其他程序即可依 ...
- STM32学习笔记(七)---SysTick
STM32学习笔记(七)-SysTick 文章目录 STM32学习笔记(七)---SysTick 一.SysTick简介 二.SysTick功能框图 三.SysTick寄存器 四.SYSTICK使用 ...
- 2022Java学习笔记七十三(异常处理:运行时异常、编译时异常、异常的默认处理的流程)
2022Java学习笔记七十三(异常处理:运行时异常.编译时异常.异常的默认处理的流程) 一.异常体系 1.Exception:java.lang包下,称为异常类,它表示程序本身可以处理的问题 2.R ...
最新文章
- 「完结」总结12大CNN主流模型架构设计思想
- OpenGL编程指南4:双缓冲实现运行
- asprise java_使用asprise进行图片验证码识别
- javascript事件处理程序
- vue-datepicker的使用
- TypeScript入门教程 之 const
- linux下设置程序后台运行,linux中如何让进程在后台运行
- 高阻态是0还是1_羽毛球拍穿线,先拉横线还是竖线?是否横线要比竖线高1到2磅?...
- css定位、position与float同时使用的情况
- 7.1 找寻失去的学习潜质——《逆袭大学》连载
- 高交会|华创芯光邀您一起畅游可见光通信的世界
- Oracle数据库恢复删除数据的方法
- LabVIEW编程LabVIEW开发高级数据采集技术 操作数字IO 例程与相关资料
- 使用hydra破解密码
- Python添加flac文件标签并实现wav转flac
- 俄内政部悬赏破解 Tor 匿名网络
- kuangbin带你飞专题
- Maven项目设置编码
- 图片拉伸:拉伸两边,保持中间不动
- 自动添加控件,一次提交多条记录。