码迷,mamicode.com
首页 > 其他好文 > 详细

深入Struts2配置元素

时间:2014-08-03 12:51:05      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:interceptor

本章重点描述了一下struts拦截器的使用,文章的前面顺带介绍了一下struts的Bean配置、常量配置和包配置

1、Bean配置

Struts2是一个高度可拓展的框架,框架大部分核心组件都是以配置的方式写在配置文件中的,当开发者需要替换其核心组件的时候,只需要写好自己的实现类,

然后配置到配置文件中。我们打开struts2-core-2.x.x.jar文件,打开里面的struts-default.xml文件,看到该文件配置了大量的Bean定义,该配置文件部分

代码如下所示:

	<!-- 下面是struts2定义的三个类型转换器 -->
    <bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="tiger" class="com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer"/>
    <bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="notiger" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
    <bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="struts" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
	<!-- 下面是struts2标签库处理Bean -->
	<bean type="org.apache.struts2.views.TagLibrary" name="s" class="org.apache.struts2.views.DefaultTagLibrary" />
上面配置文件中配置了Struts2的核心的Bean。在struts.xml文件中Bean通常有两个作用:

(1)创建该实例Bean,作为struts2的核心Bean。

(2)Bean包含的一些静态方法需要值传入。

注意,对绝大多数Struts2的应用而言,无需重新定义Struts2内的核心组件,也无需在struts.xml中配置Bean标签。

2、常量配置

前面说了,这块可以在struts.xml中配置,也可以在struts.properties中配置,其实还可以在web.xml加载FilterDispatcher的时候加载常量参数。

在struts.xml中配置的方式:<constant name="struts.multipart.maxSize" value="9000000"/>

3、包配置

Struts2的核心就是Action、拦截器,Struts2使用包来管理Action和拦截器。每个包下就是多个Action、多个拦截器、多个拦截器的引用的集合。

配置包时必须指定name属性,除此之外还可以指定一个可选属性extends,extends属性值必须是另一个包的name属性的值,使用exdends属性的目的是继承

其他包,继承父包中的Action、拦截器等配置。

除此之外,Struts2还提供了一种抽象包,抽象包的含义是该包不能有Action的定义。为了显示指定一个抽象包,必须将package元素的abstract属性设置成

true。

namespase用来指定命名空间是一个可选属性。

考虑到同一个应用可能会用到同名的Action,Struts2以命名空间的方式来管理它们,同一个命名空间下不能有相同的Action,不同的命名空间下可以有相同的

Action。

Struts2不支持为单独的Action设置命名空间,而是通过为package指定namespase属性来为该包下的所有Action统一指定命名空间。

<?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="org"   extends="struts-default">	
		<action name="login" class="org.LoginAction">
			<result name="error">/error.jsp</result>
			<result name="success">/welcome.jsp</result>
		</action>
	</package>
	<package name="get" extends="struts-default"  namespace="/apple">
		<action name="login"  class="org.UserAction">
			<result name="login">/login.jsp</result>
		</action>
	</package>	
</struts>
对于上面的这个配置文件,配置了两个包,一个是org一个是get,其中get包设置了namespase属性/apple,对于org包而言,没有设置namespase属性。

对于没有配置namespase属性的包,其为默认包,默认的namespase=" "

当为某个包配置了namespase属性的时候,那么访问的时候就需要是namespase的值加上Action的值。访问路径:

/**
其中strutsDemo是项目名称,apple是命名空间,login是Action的name
*/
http://localhost:8080/strutsDemo/apple/login

除此之外,struts还可以通过namespase="/"来指定根命名空间。

如果Url为/apple/login 那么系统首先会在命名空间为apple的包下寻找name值为login的Action,如果该包下找到了那么就处理请求,如果没有找到,继续在

默认命名空间中寻找,如果找到则处理请求,如果还没找到,那么抛出异常。

如果Url为/login,则首先会在根命名空间中寻找,其次去默认命名空间中寻找,如果两者都没有找到,抛出异常。

4、拦截器的配置

这部分很重要!!!

(1)理解拦截器

struts2拦截器是在访问某个action或者某个action方法的,访问之前或者之后实施拦截,并且Struts2拦截器是可拔插的,拦截器是AOP的一种实现。

拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序连结成一条链。在访问被拦截的方法或者字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

(2)实现Struts2拦截器原理

Struts2拦截器的实现原理相对简单,当请求struts2的action时,struts2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串联成一个列表,最后一个一个的调用列表中的拦截器。

bubuko.com,布布扣

图中我们可以发现,Struts2的Interceptor一层一层的把action包裹在最里面,这样的结构,大概有以下一些特点:
1)、整个结构就如同一个堆栈,除了Action以外,堆栈中的其他元素是Interceptor
2)、Action位于堆栈的底部。由于堆栈“先进后出”的特性,如果我们试图把Action拿出来执行,我们必须首先把位于Action上端的所有Interceptor拿出来执
行。这样,整个执行就形成了一个递归调用。
3)、每个位于堆栈中的Interceptor,除了需要完成自身的逻辑外,还需要完成一个特殊的职责。这个执行职责有三种选择:
中止整个执行,直接返回一个字符串作为relultCode
通过递归调用负责调用堆栈中下一个Interceptor的执行
如果在堆栈内已经不存在任何的Interceptor,那么调用Action
(3)部署拦截器
为了能够正常使用拦截器,首先我们必须在struts.xml中正确部署拦截器。具体的做法为在<interceptor></interceptor>标签对内使用<interceptor/>标签
引入具体拦截器,需要指定拦截器的名称和类:
<?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="wwfy" extends="struts-default">
        <interceptors>
            <interceptor name="拦截器名称1" class="拦截器类1" />
            <interceptor name="拦截器名称2" class="拦截器类2" />
            ………………………………………………………………………………………………………………………………………………
            <interceptor name="拦截器名称N" class="拦截器类N" />
        </interceptors>
        <!--省略Action配置信息-->
    </package>
</struts> 
部署好拦截器之后,我们就可以利用拦截器为指定的Action应用添加功能了。具体的做法是在<action></action>标签对内使用<interceptor-ref/>标签引入所
需的拦截器:
<?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="wwfy" extends="struts-default">
        <!--省略拦截器配置信息-->
         
        <action name="Action名" class="Action类">
            <!--省略Action结果配置信息-->
            <interceptor-ref name="defaultStack"/>
            <interceptor-ref name="拦截器名1"/>
            <interceptor-ref name="拦截器名2"/>
            ……………………………………………………………………………………………………
            <interceptor-ref name="拦截器名N"/>
        </action>
    </package>
</struts>
还可以为拦截器设置参数:
<?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="wwfy" extends="struts-default">
        <interceptors>
            <interceptor name="拦截器名称" class="拦截器类" >
                <param name="参数名">参数值</param>
            </interceptor>
        </interceptors>
        <action name="Action名" class="Action类">
            <!--省略Action结果配置信息-->
            <interceptor-ref name="拦截器名">
                <param name="参数名">参数值</param>
            </interceptor-ref>
        </action>     
    </package>
</struts> <span style="font-family:SimSun;font-size:12px;">
</span>

(4)如何使用拦截器栈

一个拦截器栈可以包括一个或者多个拦截器,也可以包括其他拦截器栈。

<?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="wwfy" extends="struts-default">
        <interceptors>
            <interceptor name="拦截器名称1" class="拦截器类1" />
            <interceptor name="拦截器名称2" class="拦截器类2" />
            ………………………………………………………………………………………………………………………………………………
            <interceptor name="拦截器名称N" class="拦截器类N" />
             
            <interceptor-stack name="拦截器栈1">
                <interceptor-ref name="拦截器名称1"/>
                <interceptor-ref name="拦截器名称2"/>
                <interceptor-ref name="拦截器名称N"/>
            </interceptor-stack>
             
            <interceptor-stack name="拦截器栈2">
                <interceptor-ref name="拦截器栈1"/>
                <interceptor-ref name="拦截器名称3"/>
            </interceptor-stack>
        </interceptors>   
    </package>
</struts>

为Action应用拦截器栈的方式和应用拦截器一样。

(5)自定义拦截器

自定义拦截器有2种实现方式,一种是实现Interceptor接口,另一种是继承AbstractInterceptor类。

看下实现Inteceptor接口的示例:

package wwfy.interceptor;

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

@SuppressWarnings("serial")
public class CustomInterceptor1 implements Interceptor {
    public void destroy() {
        // TODO Auto-generated method stub
    }
    public void init() {
        // TODO Auto-generated method stub
    }

    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("--------拦截器开始----------");
        String result = invocation.invoke();
        System.out.println("--------拦截器结束----------");
        return result;
    }

}
看下继承AbstractInterceptor类的实例:

package wwfy.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
@SuppressWarnings("serial")
public class CustomInterceptor2 extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("--------拦截器开始----------");
        String result = invocation.invoke();
        System.out.println("--------拦截器结束----------");
        return result;
    }

}

invocation.invoke()的作用:

在这个实现类中,实际上已经实现了最简单的拦截器的雏形。或许大家对这样的代码还比较陌生,这没有关系。我在这里需要指出的是一个很重要的方法

invocation.invoke()。

这是ActionInvocation中的方法,而ActionInvocation是Action调度者,所以这个方法具备以下2层含义:

如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。

如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。

所以,我们可以发现,invocation.invoke()这个方法其实是整个拦截器框架的实现核心。基于这样的实现机制,我们还可以得到下面2个非常重要的推论:

如果在拦截器中,我们不使用invocation.invoke()来完成堆栈中下一个元素的调用,而是直接返回一个字符串作为执行结果,那么整个执行将被中止。

我们可以以invocation.invoke()为界,将拦截器中的代码分成2个部分,在invocation.invoke()之前的代码,将会在Action之前被依次执行,而在

invocation.invoke()之后的代码,将会在Action之后被逆序执行。

由此,我们就可以通过invocation.invoke()作为Action代码真正的拦截点,从而实现AOP。 

深入Struts2配置元素,布布扣,bubuko.com

深入Struts2配置元素

标签:interceptor

原文地址:http://blog.csdn.net/caohaicheng/article/details/38355637

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!