Struts2的拦截器

      拦截器是Struts2框架的重要组成部分,Struts2的很多重要功能都是构建在拦截器之上的,如数据校验,转换器,国际化等。Struts2利用其内建的拦截器可以完成大部分操作,当内置拦截器不能满足时,开发者也可以自己扩展。可以说,Struts2框架之所以简单易用,与拦截器的作用是分不开的。

一,拦截器的配置

   1,拦截器

        想要让拦截器起作用,首先要对它进行配置。拦截器的配置是在 struts.xml 文件中完成的,它通常以
<interceptor>标签开头,以</interceptor>标签结束。定义拦截器格式如下:
      
<interceptor name="interceptorName" class="interceptorClass">
       	<param name="paramName">paramValue</param>
</interceptor>
name:用来指定拦截器的名称
class:用来指定拦截器的实现类
param:需要传入参数,name是参数名,paramValue是参数值

2,拦截器栈
 在实际开发中,经常需要在Action执行前同时执行多个拦截器动作,如用户登录检查,登录日志记录 以及权限检查等,这时,可以把多个拦截器组成一个拦截器栈。在使用时,可以将栈内多个拦截器当成一个整体
来引用。当拦截器被附加到一个Action上时,在执行Action之前必须先执行拦截器栈中的每一个拦截器。
 定义拦截器栈用<interceptors>元素和<interceptor-stack>子元素,当配置多个拦截器时,需要使用
<interceptor-ref>元素来指定多个拦截器,配置语法:
<interceptors>
      	<interceptor-stack name="interceptorStackName">
      	   <interceptor-ref name="interceptorName">
      	   	....
      	   </interceptor-ref>
      </interceptor-stack>
    </interceptors>
interceptorStackName:拦截器栈名称
interceptorName :拦截器名称

除此之外,在一个拦截器栈中还可以包含另一个拦截器栈:

<package name="default" extends="struts-default">
      <interceptors>
      	<interceptor name="interceptor1" class="interceptorClass"/>
      	<interceptor name="interceptor2" class="interceptorClass"/>
      	
      	<interceptor-stack name="myStack">
      		<interceptor-ref name="defaultStack"/>
      		<interceptor-ref name="interceptor1"/>
      		<interceptor-ref name="interceptor2"/>
      	</interceptor-stack>
      	
      </interceptors>
    </package>
在上述代码中,定义的拦截器栈是myStack,在myStack栈中,除了引用了两个自定义的拦截器外,还引用
了一个内置拦截器栈defaultStack,这个拦截器是必须要引入的。

3,默认拦截器

 如果想对一个包下的Action使用相同的拦截器,则需要为该包中的每个Action都重复指定同一个拦截器,
这样写显然过于烦琐。这时,可以使用默认拦截器,默认拦截器对其指定包中所有Action都能起到拦截的作用。
一旦指定了默认拦截器,如果没有显示的指定拦截器,则会使用默认拦截器,否则,默认拦截器将会被屏蔽。
 默认拦截器的语法需要使用<default-interceptor-ref>元素,次元素为package的子元素。
<default-interceptor-ref name="interceptorName"/>
interceptorName是必须已存在的拦截器或拦截器栈的名称
实例:
<package name="default" extends="struts-default">
      <interceptors>
      	<interceptor name="interceptor1" class="interceptorClass"/>
      	<interceptor name="interceptor2" class="interceptorClass"/>
      	
      	<interceptor-stack name="myStack">
      		<interceptor-ref name="defaultStack"/>
      		<interceptor-ref name="interceptor1"/>
      		<interceptor-ref name="interceptor2"/>
      	</interceptor-stack>
      	
      </interceptors>
      
      <default-interceptor-ref name="myStack"/>
      <action name="login" class="cn.itcast.action.LoginAction">
      	<result name="input">/login.jsp</result>
      </action>
      
    </package>

这个默认拦截器将会作用于包下所有的Action


Struts2的内建拦截器可以在 struts-default.xml 文件中查看




二,自定义拦截器

 在实际开发过程中,Struts2的内置拦截器虽然可以完成大部分的拦截任务,但是一些与系统逻辑相关
的通用功能,则需要通过自定义拦截器来实现。
 开发自己的拦截器,需要直接或间接的实现com.opensymphony.xwork2.interceptor.Interceptor
接口,具体代码如下:
public interface Interceptor extends Serializable {
	void init();
	void destroy();
	String intercept(ActionInvocation invocation)throws Exception;
}
该接口提供了以下三个方法
void init():拦截器被创建后会立即被调用,他在拦截器的生命周期内只被调用一次。在该方法中对相关资源
  进行必要的初始化

void destroy();该方法与init()方法相对应,在拦截器实例被销毁之前,将调用该方法来释放与拦截器
   相关的资源。他在拦截器生命周期内也只被调用一次

String intercept(ActionInvocation invocation)throws Exception:拦截器的核心方法,用来添加真正执行
   拦截器工作的代码,实现具体的拦截器操作。他返回一个字符串作为逻辑视图,系统根据
   返回的字符串跳转到对应的视图资源。每拦截一个动作请求,该方法就会被调用一次。该
  方法的ActionInvocation参数包含了被拦截的Action的作用,可以通过该参数invoke()方法,
  将控制权利转给下一个拦截器过着转给Action的execute方法。
实际开发中除了实现Interceptor接口的三个方法外,更常用的是继承抽象拦截器类AbstractInterceptor。
该类实现了Interceptor接口,并且提供了init() 和destroy()的点空实现。拦截器AbstractInterceptor中
定义的方法如下:
public abstract class AbstractInterceptor implements Interceptor {
	public void init(){}
	public void destroy(){}
	public abstract String intercept(ActionInvocation invocation)throws Exception;
}


三,应用案例-使用拦截器实现权限控制

通过之前的讲解,可将自定义拦截器的使用分为以下三步:
(1)用户自定义的拦截器类,必须实现Interceptor接口是继承AbstractInterceptor类
(2)需要在struts.xml文件定义自定义拦截器
(3)在struts.xml中的Action中使用拦截器


1,在eclipse或myeclipse中创建一个web项目,将struts2的框架所需jar包添加到项目当中,然后在
WEB-INF目录下创建一个web.xml文件,并在其中注册过滤器和首页:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Jsp_Struts2_Interceptor</display-name>
  <welcome-file-list>
    <welcome-file>main.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  
</web-app>

2,在src目录下创建一个名为cn.itcast.domain的包,在改包下创建User.java的类
package cn.itcast.domain;

public class User {
	private String username;
	private String password;
	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;
	}
}
3,在src 目录下创建cn.itcast.action的包,并在改包下创建LoginAction.java的类

package cn.itcast.action;


import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cn.itcast.domain.User;

public class LoginAction extends ActionSupport implements ModelDriven<User>{

	private static final long serialVersionUID = 1L;
	private User user =new User(); 
	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		return user;
	}
	
	public String execute()throws Exception{
		ActionContext actionContext = ActionContext.getContext();
		if("tom".equals(user.getUsername())&&"123".equals(user.getPassword())){
			actionContext.getSession().put("user", user);
			return SUCCESS;
		}else {
			actionContext.put("msg", "用户名或密码不正确!");
			return INPUT;
		}
	}
	
}
4,在cn.itcast.action包下创建类BookAction
package cn.itcast.action;

import com.opensymphony.xwork2.ActionSupport;

public class BookAction extends ActionSupport{
	public String add(){
		System.out.println("book add");
		return SUCCESS;
	}
	public String del(){
		System.out.println("book del");
		return SUCCESS;
	}
	public String update(){
		System.out.println("book update");
		return SUCCESS;
	}
	public String find(){
		System.out.println("book find");
		return SUCCESS;
	}
	
}


5,在src目录下创建一个cn.itcast.interceptor的包,并在改包下创建拦截器PrivilegeInterceptor

package cn.itcast.interceptor;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class PrivilegeInterceptor extends AbstractInterceptor{

	private static final long serialVersionUID = 1L;
	
	@Override
	public String intercept(ActionInvocation arg0) throws Exception {
		ActionContext actionContext =arg0.getInvocationContext();
		Object user = actionContext.getSession().get("user");
		if(user!=null){
			return arg0.invoke();
		}else {
			actionContext.put("msg", "您还未登录,请先登录");
			return Action.LOGIN;
		}
	}
	
}

6,在WebContent或WebRoot下创建三个视图文件,主页main.jsp 登录界面login.jsp 操作成功界面success.jsp
main.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>main.jsp</title>
  </head>
  
  <body>
    <a href="/Jsp_Struts2_Interceptor/book_del">book del</a><br>
    <a href="/Jsp_Struts2_Interceptor/book_add">book add</a><br>
    <a href="/Jsp_Struts2_Interceptor/book_update">book update</a><br>
    <a href="/Jsp_Struts2_Interceptor/book_find">book find</a><br>
  </body>
</html>

login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录</title>
</head>
<body>
	<center>
		${requestScope.msg}<br>
		<form action="//Jsp_Struts2_Interceptor/login.action" method="post">
			<table>
				<tr>
					<td><label style="text-align:right">用户名:</label></td>
					<td><input type="text" name="username"/></td>
				</tr>
				<tr>
					<td><label style="text-align:right">密码:</label></td>
					<td><input type="password" name="password"/></td>
				</tr>
				<tr>
					<td align="right" colspan="2">
						<input type="submit" value="登录" />
					</td>
				</tr>
			</table>
		</form>
	</center>
</body>
</html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>成功页面</title>
</head>
<body>
	用户${user.username}操作成功!
</body>
</html>




7,在src目录下创建struts.xml的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
       "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" 
        "http://struts.apache.org/dtds/struts-2.5.dtd">


<struts>
  	<constant name="struts.enable.DynamicMethodInvocation" value="true"/>  
	<constant name="struts.devMode" value="true"></constant> 
    <package name="struts2" namespace="/" extends="struts-default">
     	
       <interceptors>
       		<interceptor name="privilege" class="cn.itcast.interceptor.PrivilegeInterceptor"/>
       		<interceptor-stack name="myStack">
       			<interceptor-ref name="defaultStack"/>
       			<interceptor-ref name="privilege"/>
       		</interceptor-stack>
       </interceptors>
       <global-allowed-methods>regex:.*</global-allowed-methods>  
         <action name="book_*" class="cn.itcast.action.BookAction" method="{1}">
         	
       		<result>/success.jsp</result>
       		<result name="login">/login.jsp</result>
       		<interceptor-ref name="myStack"/>
        </action>
       <action name="login" class="cn.itcast.action.LoginAction">
       	<result>/main.jsp</result>
       	<result name="input">/login.jsp</result>
       </action>	

    </package>
</struts>



8,运行程序,查看结果
项目结构:



运行后如上图,点击操作

输入错误的账户密码

输入正确账户密码 tom  123

再次点击操作

控制台输出

运行成功






































































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值