当前位置: 首页 > 编程笔记 >

Java的Struts2框架中拦截器使用的实例教程

弓温书
2023-03-14
本文向大家介绍Java的Struts2框架中拦截器使用的实例教程,包括了Java的Struts2框架中拦截器使用的实例教程的使用技巧和注意事项,需要的朋友参考一下

1、拦截器小介

拦截器的功能类似于web.xml文件中的Filter,能对用户的请求进行拦截,通过拦截用户的请求来实现对页面的控制。拦截器是在Struts-core-2.2.3.jar中进行配置的,原始的拦截器是在struts-default.xml中配置的,里面封存了拦截器的基本使用方法。
Struts2拦截器功能类似于Servlet过滤器。在Action执行execute方法前,Struts2会首先执行struts.xml中引用的拦截器,如果有多个拦截器则会按照上下顺序依次执行,在执行完所有的拦截器的interceptor方法后,会执行Action的execute方法。
Struts2的拦截器必须从com.opensymphoy.xwork2.interceptor.Interceptor中实现该接口,在被定义的拦截器中有下面三个方法需要被实现:

void destroy();  
void init();  
String intercept(ActionInvocation invocation) throws Exception; 

自定义的拦截器需要重写上面三个方法。另外Struts2的拦截器配置文件struts.xml它是继承了原始文件struts-default.xml文件的,这样在相应的<package>中就会自动拥有struts-default.xml中的所有配置信息了。具体代码如下:

<package name="demo" extends="struts-default" > ... </package> 

 

2、添加拦截器

想要使用拦截器必须要经过配置,struts2采用的是映射的方法,所以想用使用某一个功能就必须在配置文件中配置,拦截器也不例外。所以必须在package中添加相应的拦截器元素,同时将拦截器关联相应的class文件,这样在执行action前才会执行相应的拦截器,具体使用方法如下。

(1)添加配置文件struts.xml,并在该文件中添加拦截器

<package name="testLogin" namespace="/" extends="struts-default"> 
  <!-- 拦截器 --> 
  <interceptors> 
    <interceptor name="myInterceptor" class="com.interceptor.MyInterceptor"></interceptor> 
  </interceptors> 
     
  <action name="demo" class="com.action.LoginAction"> 
    <result name="error" type="redirect">/error.jsp</result> 
    <result name="success">/success.jsp</result> 
    <result name="checkError">/checkSession.jsp</result> 
    <interceptor-ref name="myInterceptor"></interceptor-ref> 
    <interceptor-ref name="defaultStack"></interceptor-ref> 
  </action> 
</package> 

上面的package中添加了一个名为myInterceptor的拦截器,并为该拦截器注册了一个java类,该类名称为MyInterceptor,并被封存在com.interceptor包中。另外还在该package中添加了相应的action,在执行该action前会首先执行myInterceptor拦截器。

(2)编写被注册的拦截器类MyInterceptor,该类必须实现com.opensymphoy.xwork2.interceptor.Interceptor接口,并重写相应的方法

package com.interceptor; 
 
import java.util.Map; 
 
import com.entity.User; 
import com.opensymphony.xwork2.ActionContext; 
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.Interceptor; 
 
public class MyInterceptor implements Interceptor{ 
 
  private User user; 
   
   
  public User getUser() { 
    return user; 
  } 
 
  public void setUser(User user) { 
    this.user = user; 
  } 
 
  @Override 
  public void destroy() { 
    // TODO Auto-generated method stub 
    System.out.println("----destroy()----"); 
  } 
 
  @Override 
  public void init() { 
    // TODO Auto-generated method stub 
    System.out.println("-----Init()-------"); 
  } 
 
  @Override 
  public String intercept(ActionInvocation invocation) throws Exception { 
    // TODO Auto-generated method stub 
    System.out.println("----intercept()------"); 
    Map<String, Object> session= invocation.getInvocationContext().getSession(); 
    if(session.get("username")!=null){ 
      System.out.println("登陆成功!");     
      //session.put("username",user.getUsername()); 
      return invocation.invoke(); 
    }else{ 
      System.out.println("登陆失败!"); 
      return "checkError"; 
    } 
  } 
 
} 

(3)经过前面两步后,拦截器已经配置完成,最后一部就是使用拦截器了,在显示页面上添加相应的标签,并为标签指定上面创建的名为demo的action,然后执行页面即可在控制台中打印出相应的拦截器内容。

<%@ 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>Insert title here</title> 
</head> 
<body> 
  <form action="demo"> 
    用户名:<input type="text" name="username"><br> 
    密 码:<input type="text" name="password"><br> 
    <input type="submit" name="ok" value="提交"> 
  </form> 
</body> 
</html> 

打印输出内容:

分析输出结果,程序编译阶段首先会去读取配置文件struts.xml,在该配置文件action中顺序查找是否添加了拦截器,如果添加了拦截器则根据拦截器名称在<interceptors>中查找是否定义了该拦截器或者拦截器栈,如果发现定义的是拦截器则根据拦截器查找对应的注册的class,最后在包内查找注册的class并执行相应的init()方法;程序运行阶段的大致流程和编译阶段类似,用户在前台提交请求后,会按照注册的action在struts.xml中查找与之相对应的,如果查找到将会查找拦截器,没有查找到的话会相应的抛错,最后执行拦截器注册类的intercept方法。

3、拦截器栈

拦截器同样有栈的概念,它是将使用的拦截器定义到共有的状态下来实现统一管理,这样在package中就可以做到拦截器的共享了,大大便利了拦截器的使用。在一个package中往往会用到重复的interceptor,如果每次都在Action中添加interceptor-ref的话就会很麻烦,那么拦截器栈就是为了解决这个问题而产生的,具体配置如下:

<package name="testLogin" namespace="/" extends="struts-default"> 
    <!-- 拦截器 --> 
    <interceptors> 
      <interceptor name="myInterceptor" class="com.interceptor.MyInterceptor"></interceptor> 
      <!-- 定义公共的拦截器链,在action标签中只需要引用拦截器链 --> 
      <interceptor-stack name="defaultstack1"> 
        <interceptor-ref name="myInterceptor"></interceptor-ref> 
        <interceptor-ref name="defaultStack"></interceptor-ref> 
      </interceptor-stack> 
    </interceptors> 
     
    <action name="demo" class="com.action.LoginAction"> 
      <result name="error" type="redirect">/error.jsp</result> 
      <result name="success">/success.jsp</result> 
      <result name="checkError">/checkSession.jsp</result> 
      <interceptor-ref name="defaultstack1"></interceptor-ref> 
    </action> 
</package> 

实例中使用了interceptor-stack来定义了一个名称为defaultstack1的拦截器栈,在该栈中添加了要执行的拦截器,把拦截器做了封装,在Action中直接调用该拦截器栈即可,实现了拦截器栈的共享。

4、默认拦截器栈

另外可以定义默认的拦截器栈,即:如果某个Action中没有定义拦截器,那么它会默认执行该公共的拦截器。它和interceptors标签属于同一等级的,使用default-interceptor-ref定义。

<package name="testLogin" namespace="/" extends="struts-default"> 
  <!-- 拦截器 --> 
  <interceptors> 
    <interceptor name="myInterceptor" class="com.interceptor.MyInterceptor"></interceptor> 
    <!-- 定义公共的拦截器链,在action标签中只需要引用拦截器链 --> 
    <interceptor-stack name="defaultinter"> 
      <interceptor-ref name="myInterceptor"></interceptor-ref> 
      <interceptor-ref name="defaultStack"></interceptor-ref> 
    </interceptor-stack> 
  </interceptors> 
   
  <!-- 定义默认的拦截器栈,会自动注册到action中 --> 
  <default-interceptor-ref name="defaultinter"></default-interceptor-ref> 
   
  <action name="demo" class="com.action.LoginAction"> 
    <result name="error" type="redirect">/error.jsp</result> 
    <result name="success">/success.jsp</result> 
    <result name="checkError">/checkSession.jsp</result> 
  </action> 
</package> 

定义的默认的拦截器栈只是在Action没有指定拦截器的情况下才执行自定义默认的拦截器栈的,如果在Action中重定义了拦截器,那么它会覆盖自定义默认的拦截器栈的。

5、不执行任何拦截器

还有一种情况是一个package中定义了默认的拦截器,但是在编写的某个Action中并不需要执行任何拦截器,那么此时可以在相应的Action中添加一个名称为defaultStack的拦截器即可,它是系统默认的拦截器,不会有任何操作。

<package name="testLogin" namespace="/" extends="struts-default"> 
  <!-- 拦截器 --> 
  <interceptors> 
    <interceptor name="myInterceptor" class="com.interceptor.MyInterceptor"></interceptor> 
    <!-- 定义公共的拦截器链,在action标签中只需要引用拦截器链 --> 
    <interceptor-stack name="defaultinter"> 
      <interceptor-ref name="myInterceptor"></interceptor-ref> 
      <interceptor-ref name="defaultStack"></interceptor-ref> 
    </interceptor-stack> 
  </interceptors> 
   
  <!-- 定义默认的拦截器栈,会自动注册到action中 --> 
  <default-interceptor-ref name="defaultinter"></default-interceptor-ref> 
   
  <action name="demo" class="com.action.LoginAction"> 
    <result name="error" type="redirect">/error.jsp</result> 
    <result name="success">/success.jsp</result> 
    <result name="checkError">/checkSession.jsp</result> 
     
    <!-- 添加defaultStack保证不执行拦截器 --> 
    <interceptor-ref name="defaultStack"></interceptor-ref> 
  </action> 
</package> 

6、拦截方法

6.1 用法
上面的拦截器只是实现了对Action的拦截,其实拦截器的功能很强大,它也可以拦截相应Action方法。和拦截Action不同的是想要拦截方法就必须继承类MethodFilterInterceptor,该类封存在xwork-core.jar中,又一次证明了WebWork是Struts2的核心。另外还需要在配置文件中添加相应的属性来确定拦截的方法和不拦截的方法,具体配置方法如下:

<package name="testLogin" namespace="/" extends="struts-default"> 
  <!-- 拦截器 --> 
  <interceptors> 
    <interceptor name="myInterceptor" class="com.interceptor.MyInterceptor"></interceptor> 
    <!-- 定义公共的拦截器链,在action标签中只需要引用拦截器链 --> 
    <interceptor-stack name="defaultinter"> 
      <interceptor-ref name="myInterceptor"></interceptor-ref> 
      <interceptor-ref name="defaultStack"></interceptor-ref> 
    </interceptor-stack> 
  </interceptors> 
   
  <action name="demo" class="com.action.LoginAction"> 
    <result name="error" type="redirect">/error.jsp</result> 
    <result name="success">/success.jsp</result> 
    <result name="checkError">/checkSession.jsp</result> 
     
    <!-- 在defaultStack中配置拦截方法,参数includeMethods中添加被拦截的方法名称,excludeMethods中添加不需要拦截的名称 --> 
    <interceptor-ref name="defaultStack"> 
      <param name="includeMethods">添加要拦截的方法名称</param><!-- 拦截方法 --> 
      <param name="excludeMethods">添加不需要拦截的方法名称</param><!-- 不拦截方法 --> 
    </interceptor-ref> 
  </action> 
</package> 

继承MethodFilterInterceptor类的相应拦截方法的类中的代码

package com.interceptor; 
 
import java.util.Map; 
import com.opensymphony.xwork2.ActionContext; 
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; 
 
public class inter extends MethodFilterInterceptor { 
 
  @Override 
  public String doIntercept(ActionInvocation invocation) throws Exception { 
    System.out.println("--intercept()--"); 
    //获取相应的Session 
    Map<String,Object> session=invocation.getInvocationContext().getSession(); 
     
    Map request=(Map)ActionContext.getContext().get("request"); 
     
    String username=(String)request.get("user.username"); 
    if(session.get("username") != null){ 
      String result=invocation.invoke(); 
       
      System.out.println("--end()--"); 
      return result; 
    } 
  } 
 
} 

6.2 Demo
来看一个拦截方法的实例,并对结果进行分析。下面的实例演示拦截方法的输出结果,在实例中分别创建了一个loginAction类,添加Action要执行的方法;Inter类,拦截器中重写MethodFilterInterceptor方法,在控制台中输出是否对某个方法进行拦截;login.jsp文件,添加三个按钮,分别演示三个方法的执行。
(1)struts.xml内方法拦截器的定义,在package中定义了一个名称为inter的拦截器,在拦截器中指定了参数,includeMethods用来拦截Method1,excludeMethods中的Method2表示不拦截Methods2方法,具体配置如下代码:

<!DOCTYPE struts PUBLIC 
     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
     "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts> 
  <constant name="struts.action.extension" value=","></constant> 
   
  <package name="login" extends="struts-default">  
    <interceptors> 
      <interceptor name="inter" class="com.interceptor.inter"> 
        <param name="includeMethods">Method1</param> <!-- 拦截Method1方法 --> 
        <param name="excludeMethods">Method2</param> 
      </interceptor> 
      <interceptor-stack name="myInterceptor"> 
        <interceptor-ref name="inter"></interceptor-ref> 
        <interceptor-ref name="defaultStack"></interceptor-ref> 
      </interceptor-stack> 
    </interceptors> 
       
    <action name="loginaction" class="com.action.loginAction"> 
      <result name="success">success.jsp</result> 
      <result name="error">error.jsp</result> 
      <result name="cancel" type="redirectAction">Welcome</result> 
      <interceptor-ref name="inter"></interceptor-ref> 
      <interceptor-ref name="defaultStack"></interceptor-ref> 
    </action> 
  </package> 
</struts> 

(2)loginAction类,配置login.jsp中的action,分别在该类中添加Method1-Method3三个方法,其中Method1被拦截,Method2和Method3不被拦截,最后我们查看输出结果。

package com.action; 
 
import com.opensymphony.xwork2.ActionSupport; 
 
public class loginAction extends ActionSupport { 
  @Override 
  public String execute() throws Exception { 
    if(this.username.equals("admin") && this.password.equals("admin")){ 
      return "success"; 
    }else if(this.username.equals("cancel") && this.password.equals("cancel")){ 
      return "cancel"; 
    }else{ 
      return "error"; 
    } 
  } 
   
  public void Method1(){ 
    System.out.println("执行方法:Method1"); 
  } 
   
  public void Method2(){ 
    System.out.println("执行方法:Method2"); 
  } 
   
  public void Method3(){ 
    System.out.println("执行方法:Method3"); 
  } 
   
  private String username; 
  private String password; 
   
  public String getUsername(){ 
    return this.username; 
  } 
   
  public void setUsername(String username){     
    this.username=username; 
  } 
   
  public String getPassword(){ 
    return this.password; 
  } 
   
  public void setPassword(String password){ 
    this.password=password; 
  } 
   
   
} 

(3)inter类,继承MethodFilterInterceptor类,用来实现拦截方法。重写doIntercept方法,在该方法中添加拦截的相应信息。

package com.interceptor; 
 
import java.util.Date; 
import java.util.Map; 
 
import com.action.loginAction; 
import com.opensymphony.xwork2.ActionContext; 
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; 
 
public class inter extends MethodFilterInterceptor { 
   
  @Override 
  protected String doIntercept(ActionInvocation invocation) throws Exception { 
    // TODO Auto-generated method stub  
     System.out.println("拦截器在Action执行前拦截"+new Date());  
     String result=invocation.invoke(); //执行Action方法 
     System.out.println("拦截器在Action执行后拦截"+new Date());  
    return result;  
 
  } 
 
} 

(4)login.jsp,在jsp页面上添加三个按钮,分别演示三个方法,判断拦截器对方法的拦截情况。三个按钮在点击后回发的action是在javascript中动态的进行添加的,这样做达到了一个form中执行不同的action的方法,当然还有其它的方法,将会在下篇文章中讨论。

<%@ 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>Insert title here</title> 
<script type="text/javascript"> 
   
  //方法1,定义被拦截的方法的实例 
  function method1(){ 
    var form=document.forms[0]; 
    form.action="loginaction!Method1"; 
    form.submit(); 
  } 
   
  //方法2,为按钮2添加不拦截的方法 
  function method2(){ 
    var form=document.forms[0]; 
    form.action="loginaction!Method2"; 
    form.submit(); 
  } 
   
  //方法3,为按钮3添加不拦截的方法 
  function method3(){ 
    var form=document.forms[0]; 
    form.action="loginaction!Method3"; 
    form.submit(); 
  } 
</script> 
</head> 
<body> 
  <form> 
    用户名:<input type="text" name="username"><br> 
    密   码:<input type="text" name="password"><br> 
    <input type="submit" name="ok" value="按钮1" onclick="method1()"> 
    <input type="submit" name="ok1" value="按钮2" onclick="method2()"> 
    <input type="submit" name="ok2" value="按钮3" onclick="method3()"> 
  </form> 
</body> 
</html> 

运行完成后的页面视图:

(5)分析运行结果,分别单击按钮1、2、3,在控制台中输出结果,按钮1是绑定的method1,该方法在struts.xml中进行了拦截如果结果正确的话会显示被拦截的结果,而相应的按钮2和3只输出运行结果,因为它们没有被拦截。那看下面的结果图:

结果图正好正是了我们的分析结果,按钮1被拦截了,执行了inter类中的doIntercept方法,二相应的按钮2和3没有被拦截。也就是说,Method1被放到了方法拦截器的白名单内,执行要拦截该方法;Method2被放到了拦截器黑名单内,不需要拦截该方法;Method3不做任何处理。

7、结语

对于拦截器的内容就总结到这里,拦截器提供了很强大的功能,使得开发人员能够在运行时控制输出结果,增加了编程的灵活性。另外对于任何理论性的东西都不要试图去记忆,一定要理性的去分析,多多实践,动手做几个实例,分析结果更深刻的理解。

PS: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

Validation Interceptor

validation

使用action-validation.xml文件中定义的内容校验提交的数据。

Workflow Interceptor

workflow

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

Parameter Filter Interceptor

N/A

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

Profiling Interceptor

profiling

通过参数激活profile

 类似资料:
  • 本文向大家介绍Java中的Struts2框架拦截器之实例代码,包括了Java中的Struts2框架拦截器之实例代码的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Struts2框架拦截器实例的示例代码,供大家参考,具体内容如下 在看拦截器的小例子的前我们先来看看sturts2的原理   struts2自己是有拦截器的,通过拦截器可以拦截用户请求,并作出处理 拦截器作用有很多,譬如:

  • 主要内容:参考很多时候,相同的一组拦截器可以适用于不同的动作类,例如, 在上述情况下,它有许多重复工作以及不能重复使用。 幸运的是,在Struts 2自带的拦截器栈,使开发人员建立一组拦截到一个单元名为“栈名字”, 和可以通过“栈名字”引用操作它。 最佳做法 建议组合相同的一组拦截器到一个拦截器栈摆脱重复的工作,并增加了项目的可重用性。 在上面的例子更新,声明一个拦截器栈,命名为“defaultStackWit

  • 主要内容:1. 动作,2. JSP页面,3. 执行和等待拦截器,4. 示例,参考在Struts2中附带一个名为“execAndWait”一个非常有趣的“执行和等待”拦截器,这是一个非常方便的拦截器长时间运行操作在后台,显示用户的自定义的等待页面。在本教程中,它显示了一个完整的使用 Struts2 execAndWait 拦截器的例子。 1. 动作 一个普通的动作类,有一个长时间运行进程,证明了execAndWait效果。 LongProcessAction.java 2. J

  • 主要内容:Struts2框架的拦截器:,如何使用拦截器?,创建自定义的拦截器,创建拦截器类:,创建动作类:,创建视图,创建页面:,配置文件,堆叠多个拦截器:拦截器的概念是Servlet过滤器或JDK代理类一样的。拦截器允许横切功能分开实现的动作,以及框架。使用拦截器,可以实现如下: 提供预处理行动之前被称为逻辑。 提供后处理逻辑动作后被调用 捕获异常,这样可以进行替代处理。 Struts2框架提供的许多功能都使用拦截实现的例子包括异常处理,文件上传,生命周期回调和验证等事实上作为Struts2的

  • 本文向大家介绍AngularJS中的拦截器实例详解,包括了AngularJS中的拦截器实例详解的使用技巧和注意事项,需要的朋友参考一下 AngularJS中的拦截器实例详解 异步操作 有时候需要在拦截器中做一些异步操作。幸运的是, AngularJS 允许我们返回一个 promise 延后处理。它将会在请求拦截器中延迟发送请求或者在响应拦截器中推迟响应。 下面是项目中用到的代码。 感谢阅读,希望能

  • 本文向大家介绍PHP的拦截器实例分析,包括了PHP的拦截器实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP的拦截器用法。分享给大家供大家参考。具体如下: PHP提供了几个拦截器,用于在访问未定义的方法和属性时被调用,如下所示: 1、__get($property) 功能:访问未定义的属性是被调用 2、__set($property, $value) 功能:给未定义的属性设置值