3、struts2_拦截器

1理解Struts2拦截器                                                                             

a) 拦截器体系是Struts2框架的重要组成部分,我们可以把Struts2理解成一个空容器,而大量的内建拦截器完成了该框架的大部分操作。比如,

params拦截器负责解析HTTP请求的参数,并设置Action的属性,

fileUpload拦截器则负责解析请求参数中的文件域,并将一个文件域设置成Action的三个属性等这些操作都是通过Struts2的内建拦截器完成的。

b) Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP(面向切面编程,使用动态代码模式实现)的一种实现.一些需要统一处理的问题可以使用拦截器。比如 :如果需要处理action中文乱码问题就可以写一个中文乱码问题处理的拦截器,写好拦截器类后在我们action 配置中(就是struts.xml 中的<action>节点)加入该拦截器就可以了。引入拦截器的方式等下在拦截器配置中进行详细说明。

c) 拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

2Struts2拦截器执行流程                   

Struts2拦截器的执行流程类似于servlet的filter,在struts2容器启动时并根据其配置实例化并调用init方法,每次请求action时会根据action的配置调用相应的拦截器进行拦截调用拦截器的intercept方法并传入ActionInvocation对象,当所有的拦截器都执行完成后才调用action的方法(默认是execute), 这里需要注意拦截器的intercept方法如果不要终断业务逻辑必须调用ActionInvocation的invoke()方法(表示继续调用下一个intercept),action处理完成业务逻辑后会再次回到拦截执行ActionInvocation.invoke()方法后的代码逻辑。

下图为strut2拦截器的执行流程图:

拦截器时序图:

3、拦截器接口说明

a) Interceptor接口 filter

每一个拦截器都必须实现com.opensymphony.xwork2.interceptor.Interceptor接口,该接口在xwork-core的jar包中。Interceptor 接口类似于servlet的Filter接口内部有三个方法,下图为拦截器的方法清单:

方法名

参数

说明

init

当struts2容器实例化拦截器类的时候会调用拦截器的init方法,用于对拦截器类进行些初始化的工作,进行一些资源的初始化。

destroy

当struts2容器关闭并销毁拦截器时会调用该方法,进行资源释放。

intercept

ActionInvocation

Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。

接口常用方法说明

方法名称

参数

说明

invoke

调用该方法表示执行下一个拦截器,如果需要让流程继续,并将请求传送到action必须调用该方法。

getAction

得到当前请求的action实例,可用于修改action的属性值,比方说可以对action的复杂数据类型进行组装

getInvocationContext

返回ActionContext实例,可以通过该实例获取到当前请求的请求参数等。

a) ActionInvocation接口

该接口我们称之为Action调度者, 我在这里需要指出的是一个很重要的方法invocation.invoke()。这是ActionInvocation中的方法,这个方法具备以下2层含义

1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。

2. .如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。params

整个拦截器的核心部分是invocation.invoke()这个函数的调用位置。事实上,我们也正根据这句代码的调用位置,来进行拦截类型的区分的。

Struts2中,Interceptor的拦截类型,分成以下两类:

//代码。。

System.out.println(“before”);

invock. invoke();

System.out.println(“after”);

//代码
1. before 
before拦截,是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之前。这些代码,将依照拦截器定义的顺序,顺序执行
2. after 
after拦截,是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之后。这些代码,将依照拦截器定义的顺序,逆序执行

一、 拦截器配置                                                                                       

要使用拦截器.必须在struts的配置文件中进行配置

1、配置示例

<interceptors>
       <interceptor name="testInter" class="com.itjob.struts.action.MyInteseptor">
</ interceptor >
<interceptor-stack name="mystack">
        <interceptor-ref name="testInter">
        <param name="encode">utf-8</param>
    </interceptor-ref>
    	<interceptor-ref name="defaultStack"/>
    </interceptor-stack>
</interceptors>
<default-interceptor-ref name="mystack"/>
<action name="test" class="com.itjob.struts.action.TimeInterTest">
    <result name="success">/index.jsp</result>	  		
</action>

2、节点说明:

a) Interceptors

配置一个拦截器集。可以在其中定义拦截器和拦截器栈,注意该节点必须包含在<package>节点中。其中可以包含多个<interceptor><interceptor-stack>子节点

b) Interceptor

配置自定义的拦截器,其中有两个属性 name 属性表示拦截器的名称,如果某个action需要被该拦截器拦截,可通过name属性引用。Class属性表示一个实现了Interceptor接口的类的全限定类名。

c) interceptor-stack:

拦截器栈包含若干拦截器的引用,其中可以包含一个name属性,表示拦截器的名称,同interceptorname属性相同。该节点可以包含多个子节点,每个子节点表示引用一个拦截器或者拦截器栈。

如果需要自定义几个拦截器可以将它们引用到该节点组成一个拦截器栈,那么在需要使用这些拦截器的action中只要引用这个拦截器栈即可,这样的话action将会被拦截器栈中的所有拦截器拦截。

【注意】:这里必须要引用struts2的默认拦截器栈defaultStack要不然启动会报错。

【注意】:拦截的执行顺序跟栈中的位置一致

d) interceptor-ref

该节点表示引用一个拦截器或者拦截器栈,name属性指定要引用的拦截器或者拦截器栈的名称(对应拦截器或拦截器栈定义标签中的name属性),该节点可以包含多个子节点<param>等下会详解介绍。

e) default-interceptor-ref

该节点用于配置package的默认拦截器或者拦截器栈,表示package中所有的action都会被所配置的拦截器拦截。该节点属于package的子节点

注意:该节点必须在配置在action节点的前面。否则会报错

f) param

该节点用于配置拦截器的参数。每一个拦截器都可以配置参数,有两种方式配置参数,该 节点包含一个name属性表示参数名,拦截器中只需定义一个名称一致并且有get,set方法的全局变量就可以得到param标签的本体内容的值(示例中的红色部分)

一是针对每一个拦截器定义参数,二是针对一个拦截器堆栈统一定义所有的参数,拦截器中只需要定认name属性,属于<interceptor-ref>

例如:

<interceptor-ref name="validation">
       <param name="excludeMethods">myValidationExcudeMethod</param>
</interceptor-ref>
<interceptor-ref name="workflow">
       <param name="excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>
或者

<interceptor-ref name="defaultStack">
      <param name="validation.excludeMethods">myValidationExcludeMethod</param>
      <param name="workflow.excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>

注意:param的值只有在拦截action的时候才会注入,所以说在拦截器的init方法中不能得到param的值

三、Struts2(XWork)提供的拦截器的功能说明:

拦截器

名字

说明

Alias Interceptor

alias

在不同请求之间将请求参数在不同名字间转换,请求内容不变

Chaining Interceptor

chain

让前一个Action的属性可以被后一个Action访问,现在和chain类型的result(<result type=”chain”>)结合使用。

Checkbox Interceptor

checkbox

添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。

Cookies Interceptor

cookies

使用配置的name,value来是指定cookies

Conversion Error Interceptor

conversionError

将错误从ActionContext中添加到Action的属性字段中。

Create Session Interceptor

createSession

自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。

Debugging Interceptor

debugging

提供不同的调试用的页面来展现内部的数据状况。

Execute and Wait Interceptor

execAndWait

在后台执行Action,同时将用户带到一个中间的等待页面。

Exception Interceptor

exception

将异常定位到一个画面

File Upload Interceptor

fileUpload

提供文件上传功能

I18n Interceptor

i18n

记录用户选择的locale

Logger Interceptor

logger

输出Action的名字

Message Store Interceptor

store

存储或者访问实现ValidationAware接口的Action类出现的消息,错误,字段错误等。

Model Driven Interceptor

model-driven

如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。

Scoped Model Driven

scoped-model-driven

如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法将其放入Action内部。

Parameters Interceptor

params

将请求中的参数设置到Action中去。

Prepare Interceptor

prepare

如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。

Scope Interceptor

scope

将Action状态存入session和application的简单方法。

Servlet Config Interceptor

servletConfig

提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。

Static Parameters Interceptor

staticParams

从struts.xml文件中将<action>中的<param>中的内容设置到对应的Action中。

Roles Interceptor

roles

确定用户是否具有JAAS指定的Role,否则不予执行。

Timer Interceptor

timer

输出Action执行的时间

Token Interceptor

token

通过Token来避免双击

Token Session Interceptor

tokenSession

和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中

Workflow Interceptor

workflow

调用Action的validate方法,一旦有错误返回,重新定位到INPUT页面

Parameter Filter Interceptor

N/A

从参数列表中删除不必要的参数

Profiling Interceptor

profiling

通过参数激活profile

四、自定义拦截器                                                                             

自定义拦截器非常简单。

只需要简单三步:

1、 写一个java类并且实现Interceptor 或者继承AbstractInterceptor类,AbstractInterceptor抽象类比较简单只提供了initdestroy方法的空实现和一个抽象的intercept方法。如果我们的拦截器不需要初始化可以考虑继承自这个类。

public abstract class AbstractInterceptor implements Interceptor {

    public void init() {
    }
    public void destroy() {
    }
    public abstract String intercept(ActionInvocation invocation) throws Exception;
}

2、 在struts.xmlInterceptors节点中配置拦截器在拦截器配置中有比较详细的介绍

<interceptors>
    <interceptor name="testInter" class="com.itjob.struts.action.MyInteseptor"/>
</interceptors>
3、 在需要被拦截的 action 的配置中引用拦截器
<action name="point" class="com.itjob.struts.action.PointAction">
    <result name="success">/index.jsp</result>
    <interceptor-ref name="pointInterceptor"/>
 </action>

五、拦截器案例params                                                                                                       

使用自定义拦截器模拟自动注入请求参数到action,action中定义一个Point类其中有xy两个属性,通过拦截器将界面表单的xy表单域的值注入到actionpoint对象中。

1、 实现思路:

在拦截的intercept 方法,通过invocation.getAction()方法得到当前请求的action实例,再通过invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);得到HttpServletRequest实例,注意因为get方法返回的是Object类型所以这里必须进行类型强转。然后将request中的值设置到action中。因为在一次请求当中action的实例是同一个所以action中的point对象就有xy的值了。实现方式,在point.jsp界面点击提交后提交到PointActionAction中不作任何处理只是跳转到index.jspindex.jsp中通过action中的point属性将xy显示出来。

2、 代码示例:

Point类:

 

package com.itjob.struts.pojo;

public class Point {

	private int x;
	private int y;
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	
}

Index.jsp

<body>
    <form action="point" method="post">
    	<input type="text" name="x">
    	<input type="text" name="y">
    	<input type="submit" />
    </form>
  </body>

PointAction.java

package com.itjob.struts.action;
import com.itjob.struts.pojo.Point;
import com.opensymphony.xwork2.Action;

public class PointAction {

	private Point point = new Point();

	public Point getPoint() {
		return point;
	}

	public void setPoint(Point point) {
		this.point = point;
	}
	public String execute(){
		return Action.SUCCESS;
	}
}

Struts.xml

<action name="point" class="com.itjob.struts.action.PointAction">
    	<result name="success">/index.jsp</result>
</action>

Index.jsp

<body>
    x:${point.x }y:${point.y }
</body>

PointInterceptor.java

public class PointInteseptor implements Interceptor {

	public void destroy() {
	}

	public void init() {
	}

	public String intercept(ActionInvocation invocation) throws Exception {
		//得到request对象
				HttpServletRequest req = (HttpServletRequest)invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
				//获取请求参数
				String x = req.getParameter("x");
				String y = req.getParameter("y");
				//得到当前的action实例
				Object action = invocation.getAction();
				//判断是否是PointAction类型
				if(action instanceof PointAction){
					//类型强转
					PointAction pa = (PointAction)action;
					//将实例化一个Point对象 并且将请求参数中的x和y设置到action实例
					Point p = new Point();
					p.setX(Integer.parseInt(x));
					p.setY(Integer.parseInt(y));
					pa.setPoint(p);
				}
				return invocation.invoke();
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未名胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值