`
在水伊方
  • 浏览: 111556 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

Struts2--自定义拦截器

 
阅读更多

为什么会有拦截器:

许多Action都需要做一些相同的事情,比如说登录验证,表单输入验证,上传文件时的初始化操作,而有些Action则需要在页面显示前做一些预先填充数据的准备,这些需求在项目中都是很常见的,设想一下,如果在每个action都做一些重复性的功能逻辑,这样实现即繁琐,又违背了软件复用的思想,所以为了解决这个问题,Struts2的设计者们把这些共有的逻辑独立出来,实现成一个个的拦截器,拦截器由此而诞生。

 

什么是拦截器:

拦截器,在AOPAspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作,拦截是AOP的一种实现策略。

谈到拦截器,还有一个词需要提一下——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用,访问完之后,拦截器链中的拦截器就会按其之前定义的顺序被逆序调用。

 

理解拦截器:

拦截器是在某个Action被调用之前与之后执行的,许多框架的核心功能都实现为拦截器,如重复提交,类型转换,校验,文件上传等等,这些实现多亏了拦截器才得以简单实现,每个拦截器都是可插拔的,所以你可以精确为某个需要某种功能的Action配置相应的拦截器。

可以为每个Action配置拦截器,用户自定义的拦截器可以与框架附带的拦截器混合搭配使用,拦截器会在Action执行前做很多繁琐的事情,这样就避免了在每个Action中出现重复代码。

 

    下面是Action的生命周期图:

 

 

从图中可以看出Struts2Interceptor一层一层把Action包裹在最里面,所有的用户请求都会被拦截器所拦截,然后交给Action处理,处理结果以逻辑视图方式返回给用户。而这个调用执行流程,是由Struts 2的配置文件来实现的。可以定义一个拦截器栈为多个拦截器指定执行顺序,在某些时候,拦截器栈中的拦截器的执行顺序是非常重要的。 

       

每个位于堆栈中的Interceptor,除了需要完成它自身的逻辑,还需要完成一个特殊的执行职责。这个执行职责有3种选择:

1) 中止整个执行,直接返回一个字符串作为resultCode

2) 通过递归调用负责调用堆栈中下一个Interceptor的执行

3) 如果在堆栈内已经不存在任何的Interceptor,调用Action 

      

Struts2的拦截器结构的设计,实际上是一个典型的责任链模式的应用。首先将整个执行划分成若干相同类型的元素,每个元素具备不同的逻辑责任,并将他们纳入到一个链式的数据结构中(我们可以把堆栈结构也看作是一个递归的链式结构),而每个元素又有责任负责链式结构中下一个元素的执行调用。

 

 

拦截器都是通过代理的方式调用的,当用户请求到达Struts 2ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(List),然后逐个地调用列表中的拦截器,拦截器时序图如下图所示。 

 

从上图中可以看出,拦截器的执行顺序是:

Action之前,拦截器的执行顺序与堆栈中定义的一致;而在ActionResult之后,拦截器的执行顺序与堆栈中定义的顺序相反。这就好比我们穿衣服一样,早上起床一件一件的套在身上,晚上睡觉前,再一件一件的脱下来。 

 

配置拦截器:      

<interceptors>
	<interceptor name="拦截器名" class="拦截器对应的类" />
	<interceptor-stack name="拦截器栈名">
		<interceptor-ref name="拦截器名或拦截器栈名1" />
		<interceptor-ref name="拦截器名或拦截器栈名2" />
	</interceptor-stack>
</interceptors>

   引用拦截器:  

<action name="Action的名称" class="Action对应的类">
	<result name="success">视图资源</result>
	<!-- 使用拦截器,一般配置在result之后, -->
	<interceptor-ref name="拦截器名或拦截器栈名" />
</action>

   此处需要注意的是,如果为Action指定了一个拦截器,则系统默认的拦截器栈将会失去作用。为了继续使用默认拦截器,我们可以在配置文件中手动引入默认拦截器。

 

<action name="Action的名称" class="Action对应的类">
	<result name="success">视图资源</result>
	<!-- 使用拦截器,一般配置在result之后, -->
	<interceptor-ref name="defaultStack"/>
	<interceptor-ref name="拦截器名或拦截器栈名" />
</action>

       需要把默认的拦截器放在自定义的拦截器前面,否则会出错。 

如果不想为每个Action都配置相同的拦截器或拦截器栈,则可以在配置文件中定义一个默认的拦截器或拦截器栈

<!-- 这句是设置所有Action自动调用的拦截器堆栈 --> 
<default-interceptor-ref name="拦截器名或拦截器栈名" />
<action name="Action的名称1" class="Action对应的类1" />
<action name="Action的名称2" class="Action对应的类2" />

 注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。

 

自定义拦截器:      

自定义一个拦截器需要三步:

1 、自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。

2strutx.xml中注册上一步中定义的拦截器。

3 、在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。 

 

    所有的Struts 2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor该接口提供了三个方法:

1)      void init(); 在该拦截器被初始化之后,在该拦截器执行拦截之前,系统回调该方法。对于每个拦截器而言,此方法只执行一次。

2)      void destroy();该方法跟init()方法对应。在拦截器实例被销毁之前,系统将回调该方法。

3)    String intercept(ActionInvocation invocation) throws Exception; 该方法是用户需要实现的拦截动作。该方法会返回一个字符串作为逻辑视图。

除此之外,继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor是更简单的一种实现拦截器类的方式,因为此类提供了init()destroy()方法的空实现,这样我们只需要实现intercept方法。

 

下面是一个用于验证是否登录的拦截器:

package com.struts.interceptor;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class PermissionInterceptor implements Interceptor {

	private static final long serialVersionUID = -1615930166094288049L;

	public void destroy() {
	}

	public void init() {
	}

	public String intercept(ActionInvocation invocation) throws Exception {
		ActionContext ac = ActionContext.getContext();

		Object name = ac.getSession().get("user");

		if (name != null) {
			return invocation.invoke(); // 返回代表视图的字符串,如果还有拦截器则继续执行
		} else {
			return "error";
		}
	}
}

 

简陋的不能在简陋的登陆页面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>
	<% request.getSession().setAttribute("user", "jetty"); %>
	用户登录
</body>
</html>

 

 如果用户访问过该页面,则在session域中存放键为user,值为jetty的键值对。

 

 下面是配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<package name="struts" namespace="/test" extends="struts-default">
		<interceptors>
			<!-- 自定义拦截器  -->
			<interceptor name="permissionInterceptor" class="com.struts.interceptor.PermissionInterceptor" />
			
			<interceptor-stack name="permissionStack">
				<!-- 默认的拦截器栈,定义在struts2-core-2.3.8.jar的struts-default.xml中,
				             因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,
				             所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。-->
				<interceptor-ref name="defaultStack" />
				<interceptor-ref name="permissionInterceptor" />
			</interceptor-stack>
		</interceptors>
	
		<global-results>
			<result name="error">/WEB-INF/pages/error.jsp</result>
		</global-results>
		
		<action name="view" class="com.struts.action.ViewInfoAction" method="execute">
			<!-- 引用拦截器   -->
			<interceptor-ref name="permissionStack" />
			<result name="success">/WEB-INF/pages/viewinfo.jsp</result>
		</action>
	</package>
</struts>

 

简单的Action:

package com.struts.action;

public class ViewInfoAction {
	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
	
	public String execute() {
		this.message = "Hello, my name is Jetty";
		return "success";
	}

}

 

 如果用户没有访问过login.jsp,而直接访问名称为view的action,则会跳转到error.jsp

简单的error.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>
	您没有权限查看该页面,请登录后查看!
</body>
</html>

 如果用户访问过login.jsp,则用户访问名称为view的action时,会跳转到viewinfo.jsp

简单的viewinfo.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="ISO-8859-1"%>
<!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>
	${message }
</body>
</html>

 即可以在浏览器中看到Hello, my name is Jetty信息。 

 

注:Struts2默认的拦截器栈,定义在struts2-core-2.x.x.jar的struts-default.xml中

  • 大小: 17.1 KB
  • 大小: 17.5 KB
分享到:
评论

相关推荐

    struts2的一个自定义拦截器小例子

    本示例将聚焦于如何在Struts2中实现一个自定义拦截器。 首先,我们需要了解拦截器在Struts2中的作用。拦截器是AOP(面向切面编程)的一个核心概念,它允许开发者在动作执行前后插入额外的逻辑,如日志记录、权限...

    struts2--4.拦截器

    开发过程中,我们可以根据需要自定义拦截器栈,或者在默认栈基础上添加、替换拦截器。 ### 5. 自定义拦截器 自定义拦截器通常需要实现`Interceptor`接口并覆盖`intercept`方法。在这个方法里,你可以添加自己的业务...

    struts2-json-plugin源码

    4. **拦截器**:Struts2的拦截器机制允许在Action调用前后执行特定逻辑。JSON插件可能包含用于处理JSON请求和响应的拦截器,比如处理JSON参数的解析和验证。 5. **Action与模型驱动**:如果Action使用模型驱动模式...

    struts2自定义拦截器

    在Struts2中,自定义拦截器是实现业务逻辑控制、数据验证、权限管理等功能的重要手段。下面将详细探讨如何在Struts2中实现自定义拦截器来完成权限拦截。 首先,我们需要了解Struts2拦截器的工作原理。拦截器是在...

    JSP 开发之Struts2内建自定义拦截器.docx

    本文将深入探讨Struts2的内建自定义拦截器及其配置。 首先,让我们理解什么是拦截器。拦截器是基于AOP(面向切面编程)思想的,它们在Action调用前后执行,形成一个拦截器链。每个拦截器都可以执行特定的任务,并且...

    struts2-016/017漏洞解决

    使用预定义的拦截器或自定义拦截器来检查和清理输入。 4. **安全编码实践**:遵循安全编码的最佳实践,避免在应用程序中直接使用不受信任的数据。尽量避免使用可能导致代码执行的OGNL表达式,除非已经进行了充分的...

    Struts2-2.5.13最新jar下载

    2. **Interceptor**:拦截器是Struts2的一个重要特性,它们是插件式的,可以插入到Action调用流程中,实现如日志、权限检查、事务管理等通用功能。 3. **Result**:结果是Action执行后返回的对象,通常用于渲染视图...

    struts2-core-2.3.7源码

    3. **Interceptor(拦截器)**: 拦截器是Struts2的核心特性,它们按照预设的顺序执行,可以在Action执行前后进行额外的操作,如日志记录、权限检查等。 4. **Value Stack**: 用于存储Action实例和其他Action上下文...

    struts2自定义拦截器配置心得

    Struts2自定义拦截器的配置是Struts2框架中一个非常重要的功能,它允许开发者在Action执行前后插入自定义的逻辑,以实现如权限验证、日志记录、性能监控等多种需求。以下是对标题和描述中涉及的知识点的详细说明: ...

    struts2-tags-文档.rar

    "struts2.chm"可能是Struts2的基础教程,涵盖了框架的基本概念、配置、动作、拦截器等核心组件。在这个文档中,你可以了解到如何设置Struts2的配置文件,如何创建Action类,以及如何使用拦截器进行业务逻辑处理。...

    struts2-2.3.4.1-all

    2. **拦截器(Interceptor)**:这是Struts2的一个强大特性,它可以拦截Action调用前后,实现事务管理、日志记录、权限验证等功能。通过配置拦截器栈,开发者可以灵活控制请求处理流程。 3. **OGNL(Object-Graph ...

    struts2 自定义拦截器.rar

    自定义拦截器是Struts2框架中一个非常重要的特性,允许开发者扩展和定制框架的行为,以满足特定的业务需求。这篇博客文章可能是关于如何在Struts2中创建和使用自定义拦截器的教程。 在Struts2中,拦截器是基于责任...

    struts2-拦截器.docx

    这里`myStack`是一个拦截器栈,包含`paramsPrepareParamsStack`(Struts2默认的参数处理拦截器栈)和`myCustomInterceptor`(自定义拦截器)。 - **Action配置**:在Action的配置中,通过`&lt;action&gt;`标签的`...

    struts-2.5.22-all.zip

    Struts2框架的优势在于其强大的拦截器(Interceptor)机制,允许开发者定义自定义的行为,如日志记录、权限检查等,可以在请求处理流程中的不同阶段插入。此外,它还支持多种结果类型,如Redirect、Stream等,方便...

    struts2-2.0.14

    此外,还包括了Interceptor(拦截器)机制,这是一种AOP(面向切面编程)的实现,允许在Action执行前后插入自定义代码,用于日志记录、权限验证等通用功能。Struts2核心库还支持OGNL(Object-Graph Navigation ...

    struts2自定义拦截器.pdf

    自定义拦截器是Struts2框架中扩展功能的重要手段,让我们深入探讨如何在Struts2中实现自定义拦截器。 首先,创建一个Web项目是基础步骤,这可以通过IDE如Eclipse或IntelliJ IDEA来完成。确保你的项目包含了Struts2...

    struts2基础--使用自定义MVC

    1. **自定义拦截器**:Struts2允许开发人员创建自己的拦截器,以扩展或修改请求处理流程。例如,可能有一个拦截器用于处理登录验证,或者用于日志记录和性能监控。 2. **自定义结果类型**:默认的结果类型可能无法...

    struts2 相关jar包 包含json-lib-2.1.jar+struts2-json-plugin-2.1.8.1.jar

    - **Interceptor(拦截器)**:这些是Struts2中的重要组件,它们在Action调用前后执行,提供了事务控制、日志记录、权限验证等功能。 - **配置文件**:通常有struts.xml或类似的配置文件,用于定义Action、结果...

    自定义拦截器struts2源代码

    本篇将深入讲解如何在Struts2中自定义拦截器,并通过提供的源代码进行分析。 拦截器是Struts2框架的核心组件之一,它允许我们在请求到达Action之前或离开Action之后执行一些额外的操作,如日志记录、权限验证、性能...

Global site tag (gtag.js) - Google Analytics