Struts2——拦截器(Interceptor)

拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也提供了一种可以提取Action中可重用的代码的方式。

1、Struts2中内置的拦截器

常见的拦截器:
(1)params拦截器
这个拦截器把请求参数设置到相应的Action的属性去,并自动进行类型转换。
(2)modelDriven拦截器
如果Action实现ModelDriven接口,它将getModel()取得的模型对象存入OgnlValueStack中。
(3)execption拦截器
顾名思义,在抛出异常的时候,这个拦截器起作用。最好把它放在第一位,让它能捕获所有的异常。
(4)validation拦截器
调用验证框架读取 *-validation.xml文件,并且应用在这些文件中声明的校验。
(5)token拦截器
核对当前Action请求(request)的有效标识,防止重复提交Action请求。
(6)fileUpload拦截器
用来处理文件上传
(7)workflow拦截器
调用Action的validate方法,一旦有错误返回,重新定位到INPUT结果视图
(8)servletConfig
通过感知接口,获取感应对象

2、自定义拦截器

(1)步骤:

①自定义一个类,继承AbstractInterceptor抽象类,或实现Interceptor接口

②在struts.xml配置文件中注册拦截器

在struts.xml配置文件中,设置默认拦截器或配置Action类的局部拦截器来使用。

(2)eg:该示例自定义拦截器拦截主页面,防止未登录用户强行登陆主页面。

①CheckLoginInterceptors.java(拦截器)

public class CheckLoginInterceptors extends AbstractInterceptor{

	private static final long serialVersionUID = 1L;
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		//获取Session对象中的用户信息
		String username = (String) ActionContext.getContext().getSession().get("USER_IN_SESSION");
		if(username!=null){
			return invocation.invoke();//如果username不为空,放行
		}
		return "input";//否则返回登录页面
	}
}
②LoginAction.java

public class LoginAction extends ActionSupport{

	private static final long serialVersionUID = 1L;
	private String username;
	private String password;
	
	@Override
	public String execute() throws Exception{
		System.out.println(username+","+password);
		//将用户名存入Session对象中
		ActionContext.getContext().getSession().put("USER_IN_SESSION", username);	
		return "success";
	}
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

③struts.xml

<package name="interPkg" extends="struts-default" namespace="/">
		<!-- 注册拦截器 -->
		<interceptors>
			<interceptor name="checkLogin" class="interceptors.CheckLoginInterceptors"/>
		</interceptors>
		<!-- 指定默认拦截器 -->
		<default-interceptor-ref name="checkLogin"/>
		<!-- 全局视图 -->
		<global-results>
			<result name="input">
				/views/login/login.jsp
			</result>
		</global-results>

		<action name="login" class="action.interceptors.LoginAction">
                       <result name="success" type="redirectAction">
				<param name="namespace">/</param>
				<param name="actionName">main</param>
			</result>
		</action>

		<action name="main">
			<result name="success" type="dispatcher">
				/views/login/welcome.jsp
			</result>
		</action>
	</package>
上述代码 存在问题

a.登陆失败,永远进不了LoginAction

原因:进入LoginAction之前,需要判断session中是否有USER_IN_SESSION,而USER_IN_SESSION只有在LoginAction中才能设置。
结论:LoginAction不需要做登陆检查。

b.在LoginAction中再也获取不了请求参数

原因:当我们在<package>设置了默认的拦截器引用,那么<package>之前的默认的拦截器栈(defaultStack)就不引用了,那么defaultStack中的获取请求参数的拦截器也不再引用。

应改为如下:

	<package name="interPkg" extends="struts-default" namespace="/">
		<!-- 注册拦截器 -->
		<interceptors>
			<interceptor name="checkLogin" class="interceptors.CheckLoginInterceptors"/>
			<!-- 自定义拦截器栈,可放置多个拦截器 -->
			<interceptor-stack name="myStack">
				<interceptor-ref name="checkLogin"/>
				<interceptor-ref name="defaultStack"/>
			</interceptor-stack>
		</interceptors>
		<!-- 指定默认拦截器 -->
		<default-interceptor-ref name="myStack"/>
		<!-- 全局视图 -->
		<global-results>
			<result name="input">
				/views/login/login.jsp
			</result>
		</global-results>
		
		<action name="login" class="action.interceptors.LoginAction">
		<!-- 配置局部拦截器 -->
		<interceptor-ref name="defaultStack"/>
			<result name="success" type="redirectAction">
				<param name="namespace">/</param>
				<param name="actionName">main</param>
			</result>
		</action>
				
		<action name="main">
			<result name="success" type="dispatcher">
				/views/login/welcome.jsp
			</result>
		</action>
	</package>

④测试



使用隐身窗口重新登陆,试图登陆主页


猜你喜欢

转载自blog.csdn.net/ack_finding/article/details/78898831