Struts2拦截器的原理

拦截器(Interceptor)是Struts 2的核心组成部分。很多功能(Feature)都是构建在拦截器基础之上的,例如文件的上传和下载、国际化、转换器和数据校验等,Struts 2利用内建的拦截器,完成了框架内的大部分操作。

Struts 2文档中对拦截器的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制,使开发者可以定义一个特定的功能模块,这个模块可以在Action执行之前或者之后运行,也可以在一个Action执行之前阻止Action执行。同时也提供了一种可以提取Action中可重用的部分的方式。

 

5.2  Struts 2拦截器

通过上一节的介绍,读者会对拦截器的原理有了一个基本的理解,本节来介绍Struts 2架构中的拦截器。

5.2.1  Struts 2拦截器原理

读者可以通过Struts 2官方文档说明来理解拦截器,如果读者具有较强的英文阅读能力,建议查阅官方使用文档(http://struts.apache.org/2.0.11/docs/interceptors.html)。如图5.4所示,是拦截器在Struts 2中的示意图。

5.4  Struts 2拦截器

从图5.4所示内容中可以看出,Struts 2架构的Action被一个或者多个拦截器(拦截器栈)所包围,所有的用户请求都会被拦截器所拦截,然后交给Action处理,处理结果以逻辑视图方式返回给用户。而这个调用执行流程,是由Struts 2的配置文件来实现的,后面会详细介绍。拦截器是Struts 2核心部分之一。

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

5.5  Struts 2拦截器时序图

Struts 2架构中,Action的调用都是通过拦截器来实现的。有的读者可能会疑惑,前几章的介绍中,没有明确说明拦截器,为什么可以直接调用Action?那是因为Struts 2架构如果不做显式的拦截器配置,则系统会调用默认的拦截器来调用Action,在用户看来,好像没有配置拦截器。系统默认的拦截器笔者后面会详细介绍。

5.2.2  HelloWorld拦截器

读者可以按照笔者的步骤,一步一步建立第一个拦截器示例,来体验Struts 2框架中拦截器带给读者的惊喜。

(1) 在配置文件中增加拦截器定义和在Action中声明拦截器。笔者建立了一个目录ch5来对应本章,ch5.xml配置文件内容如代码5.8所示。

代码5.8  HelloWorld拦截器配置文件

 

<? xml version="1.0" encoding="UTF-8"  ?>

<! DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd"
>

< struts >

    
<!--   定义包 -->

< package  name ="ch5"  extends ="struts-default"  namespace ="/ch5" >

      
<!--   定义拦截器 -->

        
< interceptors >

            
< interceptor  name ="Myinterceptor"

                class
="ch5.Myintercepor" >

            
</ interceptor >

        
</ interceptors >

        
< action  name ="Reg"  class ="ch5.Reg" >

            
< result  name ="success" > /ch5/success.jsp </ result >

            
< result  name ="input" > /ch5/reg.jsp </ result >

            
<!--   引用默认拦截器 -->

            
< interceptor-ref  name ="defaultStack" ></ interceptor-ref >

            
<!--   引用自定义默认拦截器 -->

            
< interceptor-ref  name ="Myinterceptor" ></ interceptor-ref >

        
</ action >

    
</ package >

</ struts >

 

注意

需要读者在struts.xml文件中使用<include file="/ch5/ch5.xml"></include>将该配置文件包含进去。

 

 (2)ch5包内建立一个拦截器类Myintercepor,如代码5.9所示。

代码5.9  Helloworld拦截器类Myintercepor

 

package  ch5;

import  com.opensymphony.xwork2.ActionInvocation;

import  com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public   class  Myintercepor  extends  AbstractInterceptor  {

    
//拦截方法

    
public String intercept(ActionInvocation arg0) throws Exception {

        Reg reg 
= (Reg) arg0.getAction();

        System.out.println(
"拦截器信息:HelloWorld拦截器!");

        
//执行Action或者执行下一个拦截器

        String result 
= arg0.invoke();

        
//提示Action执行完毕

        System.out.println(
"拦截器信息:Action执行完毕!");

        
return result;

    }


}


 

 (3)ch5包内建立一个业务控制器Reg,如代码5.10所示。

代码5.10  HelloWorld拦截器示例的业务控制器

 

package  ch5;

import  java.util.Date;

import  com.opensymphony.xwork2.ActionSupport;

public   class  Reg  extends  ActionSupport  {

    
//定义用户名属性

    
private String username;

    
//定义处理信息:注意同http中的msg不同名称

    
private String mymsg;

    
//定义密码属性

    
private String password1;

    
//定义确认密码

    
private String password2;

    
//定义生日属性

    
private Date birthday;

    
public String execute() throws Exception {

        
if (username != null && getPassword1().equals(getPassword2())

                
&& !getUsername().trim().equals("")) {

            
//输出调试信息

            System.out.println(
"Action信息:正在执行Actiion... ...");

            
return SUCCESS;

        }
 else {

            
return INPUT;

        }


    }


    
//getter和setter方法

    
public String getUsername() {

        
return username;

    }


    
public void setUsername(String username) {

        
this.username = username;

    }


    
public String getMymsg() {

        
return mymsg;

    }


    
public void setMymsg(String mymsg) {

        
this.mymsg = mymsg;

    }


    
public String getPassword1() {

        
return password1;

    }


    
public void setPassword1(String password1) {

        
this.password1 = password1;

    }


    
public String getPassword2() {

        
return password2;

    }


    
public void setPassword2(String password2) {

        
this.password2 = password2;

    }


    
public Date getBirthday() {

        
return birthday;

    }


    
public void setBirthday(Date birthday) {

        
this.birthday = birthday;

    }


}


 

 (4)同样在ch5包内,建立一个用户注册reg.jsp文件和一个用于显示注册成功信息的success.jsp文件。内容分别如代码5.11和代码5.12所示。

代码5.11  用户注册界面reg.jsp

 

<% @ page contentType="text/html;charset=UTF-8" language="java"  %>

<% @ taglib prefix="s" uri="/struts-tags"  %>

< html >

< head >

< title > 用户注册 </ title >

< s:head  />

</ head >

< body >

< table >

< s:form  id ="id"  action ="Reg" >

    
< s:textfield  name ="username"  label ="用户名:" />

    
< s:password  name ="password1"  label ="密码:" />

    
< s:password  name ="password2"  label ="确认密码:" />

    
< s:datetimepicker  name ="birthday"  label ="生日:" />

    
< s:submit  value ="注册" />

</ s:form >

</ table >

</ body >

</ html >

 

代码5.12  注册成功界面success.jsp

 

<% @ page contentType="text/html;charset=UTF-8" language="java"  %>

<% @ taglib prefix="s" uri="/struts-tags"  %>

< html >

< head >

< title > 注册成功界面 </ title >

< s:head  />

</ head >

< body >

< table >

< h2 > 用户名: < s:property   value ="username"   /></ h2 >

< h2 > 密码: < s:property   value ="password1"   /></ h2 >

< h2 > 生日: < s:property   value ="birthday"   /></ h2 >

</ table >

</ body >

</ html >

 

(5) 启动Tomcat服务器,在浏览器中输入:http://localhost:8080/bookcode/ch5/reg.jsp,运行界面如图5.6所示。

5.6  HelloWorld拦截器的注册界面

 (6)读者可以在“用户名”、“密码”、“确认密码”和“生日”输入框中填入相关字符串,单击“注册”按钮,会发现Tomcat控制台输出如下信息:

… …

信息: Detected AnnotationActionValidatorManager, initializing it...

拦截器信息:HelloWorld拦截器!

Action信息:正在执行Actiion... ...

拦截器信息:Action执行完毕!

… …

到此为止,第一个拦截器HelloWorld示例就建立成功了,读者通过本示例,可以了解拦截器的基本功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值