实现拦截器——自定义拦截器(下篇)

 

实现拦截器——编写自己的拦截器(下篇)

 

 

Struts2提供的拦截器机制大大提高了自身的灵活性,而且Struts2本 身提供的拦截器也为大家省了不少事,了解Struts2本身的拦截器也 是十分重要的一件事情.通过了解Struts2本身的拦截器可以使我们 编写出更强壮的拦截器.

 

 

使用预定义拦截器

在Struts2中使用拦截器需要将Action与拦截器(拦截器栈)关联起来,拦截器才可以发挥神奇的作用.在平时编写基于Struts的程序时我们并不关心拦截器(拦截器栈)的使用,这是因为Struts2默默的为我们定义了默认拦截器栈defaultStack,defaultStack中包含了经常使用的拦截器使得Struts2程序变得强大而又神奇.defaultStack中包含了以下拦截器:

 

[见附件]

拦截器-exception

-用于捕获在拦截器和Action执行中的异常信息,并根据异常类型显示不同的页面.

-创建ExceptionHolder对象,用来包装异常信息,并置入值栈中,供错误页面显示相关消息.这里要提到的是Struts2中以错误页面的方式来处理在程序执行过程中产生的异常信息,那么出现异常怎样指定错误页面呢? 别急,接着向下看.在Struts2中要处理异常信息显示错误页面,我们需要在Struts2 的配置文件中添加如下配置信息:

 

<global-results>
    <result name="error">页面</result>
</global-results>

<global-exception-mappings>
    <exception-mapping exception="异常类型" result="error">
<global-exception-mappings>

 

这些配置信息的添加是以配置文件中的包(package)为单位的,可以为每个包声明不同的错误页面.

 

 

拦截器-servletConfig

-如果Action实现了访问Servlet API的接口,如ServletContextAware,SessionAware等,这里就不一一列举了.

 

拦截器-i18n

-支持国际化的拦截器.

 

拦截器-chain

-记得两个Action互相传递参数和属性的情况吗?就是这个拦截器发挥的作用.就是让前一个Action中的参数在可以在下一个Action中可以使用.

 

拦截器-modelDriven

-某个Action实现了ModelDriven接口,通过getModel方法返回了领域模型的对象,那么modelDriven拦截器就将领域模型的对象压置值栈的栈顶,以方便设置或获得参数.

 

拦截器-staticParams

-将action配置中指定的参数值设置到Action实例中.如:

 

<action name="index" class="...">

   <param name="param">...</param>
   <result>/pages/index.jsp</result>

</action>

 

拦截器-params

-将请求参数的值设置到值栈中的属性中.

 

拦截器-conversionError

-将类型转化错误(由ActionContext中)加入到Action 的Field error中(通过addFieldError方法-接口ValidationAware中定义的方法)

 

拦截器-validation

-执行声明式校验

-如果Action所在的包中存在ActionName-validation.xml校验规则声明文件,则进行输入校验处理.有校验错误发生时,将错误消息加入Action中.

 

拦截器-workFlow

-执行编程式校验

-如果Action实现了Validateable接口,则执行编程式校验,调用其中的validate方法.

如果有校验错误消息,则终止正常流程,返回input字符串.

 

 

其它几个拦截器

在Struts2中我们最常用的就是默认的拦截器,我们在上面列举了默认拦截器栈中部分拦截器,我认为这些都是我们必须了解的,也是相当重要的,当然其中几个我没有提到,这并不意味这不重要.除去默认拦截器栈之外Struts2还定义了许多拦截器栈提供给我们使用,大家可以去Struts2-core包下找到struts-default.xml中查查看.另外还要提到timer和logger拦截器,也挺有作用的拦截器,自己去试试吧.

 

 

注意拦截器的顺序

在使用拦截器的同时也应该关心到配置拦截器时的顺序,要不然挺不让人放心的.大家可以参考一下defaultStack这个拦截器栈中拦截器的顺序,细细一想这样的顺序还是很道理的.大家可以根据拦截器执行的原理及开发时的需求细细品味一下.

 

 

模拟Struts2中的拦截器

在学习框架的同时可以适当了解一下框架的内部,自己动手来模拟一下框架中的某些功能,至于自己写好还是不好,我觉得这不是重点,重点在于What you learned. 和What you wanted.记得我在一次面试中面试管问我,能不能自己写一个ASP.NET框架,应该注意哪写方面,你自己想过这些吗?当时我就愣了,What! 我只是个小小菜鸟程序员,只是希望一点一点来,你上来就来这个啊.我晕了.然后自己就平自己的理解说了几句,估计是人家不满意,也就嗯了两句这问题也就算了.现在想起来确实平时在学习工具的同时也应该有自己的工具,也应该知道工具的应用领域,工具的构造.有些时候自己拿着钝器也能上战场,虽然割不出一个口子,小样我还拍不扁你啊.

好了言归正传,现在我来模拟一下Struts2中的ModelDriven接口实现的功能,至于为什么选择ModelDriven,看完你就知道了.

想一下我们平时使用ModelDriven时的情景,某个Action实现ModelDriven接口,在getModel方法中返回模型(Model)对象,然后在设置或取值时直接就可以使用模型中的属性了,嗯就是这样了.我们现在该怎么做呢?继续向下看.

The First.

我应该有个接口,然后接口中应该有个getModel方法,使得实现这个接口的类(Action)都允诺实现getModel方法.这样我new一个接口MyModelDriven:

 

package lele.struts2.interceptor;

public interface MyModelDriven<T> {

    T getModel();
}

 

 

这里怎里怎样让 getModel方法返回任意类型的模型(Model)对象,我使用了泛型,但在Java 1.5之前,泛型是没有的,这个问题在Struts2中怎么解决呢?没有Struts2怎么解决呢?自己试试吧.

The Second

现在我有了自己的接口,那么接下来就是某个Action实现了MyModelDriven接口并且在getModel方法中返回了模型对象,又怎样知道Action实现了MyModelDriven接口并且在getModel方法中放回了模型对象呢?事情的解决方案是这样的,要在Action实例实例化出来后,某个Action被调用之前,判断是否实现了MyModelDriven接口,如果实现了那么就执行相关工作.

到这里我理所当然的想到了Interceptor,好,马上工作:

 

package lele.struts2.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;

public class MyModelDrivenInterceptor extends AbstractInterceptor {
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		Object action = invocation.getAction();
		if (action instanceof MyModelDriven) {
			if (null != ((MyModelDriven) action).getModel()) {
				Object obj = ((MyModelDriven) action).getModel();
				ValueStack vs = invocation.getStack();
				vs.push(obj);
			}
		}
		return invocation.invoke();
	}
}
 

 

在Intercept方法中当我们判断出某个Action实现了MyModelDriven接口,那么就一定能从getModel方法中得到模型对象,当这个对象不是Null值,就把对象设置到值栈中.Invocation中提供了getStack方法来获得值栈,然后把模型对象压置栈顶.然而工作做到这还没了事,设置和取值的事现在这个MyModelDrivenInterceptor还做不了,还需要ParametersInterceptor来帮忙.那么两个拦截器的位置就需要考虑一下了.

The Last

在配置拦截器时应当把ParametersInterceptor放在前面然后才是MyModelDrivenInterceptor.大家可以思考一下这样做的目的.至于详细的部署工作和测试工作,我就不在这摆弄笔墨了.

 

 

 

好了,今天就和大家聊到这里了希望对Struts2中的拦截器的理解再升级一个档次.下次我们再见。

 

 

       PS:大家可以联系我


Mail: wanglehappy9112@gmail.com

MSN:wang4717@live.cm

QQ:  471776739

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值