bean的配置
struts2是一个可扩展的框架,核心组件都是可以配置的,这些组件通过struts2自己的依赖注入容器来装配。
在struts-default.xml文件中,定义了struts2框架的可配置组件,例如:

<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="xwork" class="com.opensymphony.xwork2.DefaultActionProxyFactory" />
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="struts" class="org.apache.struts2.impl.StrutsActionProxyFactory" />
<bean class="com.opensymphony.xwork2.ObjectFactory" static="true" />

可以配置两种用途的Bean:
1、框架的IOC容器创建bean的实例,然后将该实例注入到框架的内部对象中
2、通过bean的静态方法向bean注入值
第一种用法中,bean将被注入到框架内部和内部对象协作,框架要知道bean的类型,因此在配置bean时,通常用使用type属性,以指明bean实现的接口。例如,我们创建了自己的ObjectFactory,可以在struts.xml文件中使用bean配置:

<struts>
    <bean type="com.opensymphony.xwork2.ObjectFactory" name="myfactory" class="com.company.myapp.MyObjectFactory" />
</struts>

在第二种用法中,使用值注入,允许不创建bean,而让bean接收框架的常量。bean使用值注入,必须使用static属性,例如struts-default.xml文件中一个配置项:

<bean class="com.opensymphony.xwork2.ObjectFactory" static="true" />

在实际开发中我们很少用到bean元素,因为我们一般不会去扩展或者替换strut2的核心组件。
常量(Constant)的配置
通过常量的配置,可以改变struts2框架和插件的行为,从而满足不同web应用的需求。
在struts.xml中的常量配置:

<struts>
    <constant name="struts.devMode" value="true" />
</struts>

在struts.properties中的常量配置
struts.devMode=true
在web.xml中的常量配置

<filter>
    <filter-name>struts</filter>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    <init-param>
        <param-name>struts.devMode</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

包(package)配置
struts2中的包类似于Java中包,提供了将action、result、result类型、拦截器和拦截器栈组织为一个逻辑单元的一种方式,提高重用性。与Java中的包不同的是,struts2中的包可以扩展另外的包,从而“继承”原有包的所有定义,包括所有的action、result、拦截器和拦截器栈,并可以添加自己包特有的配置,以及修改原有包的部分配置。
在struts.xml文件中使用package元素来定义包。package元素有一个必须的属性name,指定包的名字,这个名字将作为引用该包的键(key)。包的名字必须是唯一的,package元素的extends属性是可选的,允许一个包继承一个或多个实现定义的包中的配置,如果指定多个包,则以逗号分隔。
例如:

<struts>
    <!--定义了一个名为default的包,继承自struts-default.xml文件中定义的struts-default抽象包-->
    <package name="default" extends="struts-default">
    <interceptors>
        <!--定义名为crudStack的拦截器栈-->
        <interceptor-stack name="crudStack">
            <interceptor-ref name="checkbox" />
            <interceptor-ref name="params" />
            <interceptor-ref name="static-params" />
            </interceptor-ref name="defaultStack" />
        </interceptor-stack>
    <action name="viewSource" class="org.apache.struts2.showcase.source.ViewSourceAction">
        <result>viewSource.jsp</result>
    </action>
    </package>

    <!--定义了一个名为skill的包,继承自先前定义的default包-->
    <package name="skill" extends="default" namespace="/skill">
        <!--设置默认的拦截器引用,crudStack是从default包继承而来的-->
        <default-interceptor-ref name="crudStack" />
        <action name="list" class="org.apache.struts.showcase.action.SkillAction" method="list">
            <result>/empmanager/listSkills.jsp</result>
            <!--设置action引用的拦截器,将覆盖默认的拦截器引用-->
            <interceptor-ref name="basicStack" />
        </action>
        <action name="list" class="org.apache.struts.showcase.action.SkillAction" method="list">
            <result>/empmanager/editSkills.jsp</result>
            <!--设置action引用的拦截器,将覆盖默认的拦截器引用-->
            <interceptor-ref name="params" />
            <interceptor-ref name="basicStack" />
        </action>
    </package>

    <!--定义一个名为employee的包,继承自先前定义的default包-->
    <package name="employee" extends="default" namespace="/employee">
        <default-interceptor-ref name="crudStack" />
        <action name="list" class="org.apache.struts2.showcase.action.EmployeeAction" method="list">
            <result>/empmanager/listSkills.jsp</result>
        </action>
        <!-- 设置mode拦截器引用,basicStack是从struts-default包继承而来的-->
        <interceptor-ref name="basicStack" />
    </package>

</struts>

包含(include)的配置
include元素只有一个必须的属性file,指定被包含文件的文件名,例如:

<struts>
    <include file="struts-chat.xml" />
</struts>

需要注意的是,每一个被包含的文件都必须和struts.xml具有相同的格式,被包含的文件本身也是完整的配置文件。
如果被包含的配置文件和struts.xml不在同一个目录下,例如放到org/sunxin/user目录下,配置文件:

<include file="org/sunxin/user/struts-user.xml" />

拦截器(interceptor)配置
拦截器允许你在action的执行的前后插入代码执行。struts2中的拦截器是一个强有力的工具,他可以为action动态添加输入验证、对象组装、权限控制、日记记录等,而不需要修改action。
要为action配置引用的拦截器,首先需要在interceptors元素中使用interceptor元素定义拦截器,然后在action元素中使用interceptor-ref元素指定引用的拦截器。interceptor元素有两个必需的属性:name和class,前者指定拦截器的名字,后者指定拦截器的完整类名。假如我们要为ResourceAction配置两个拦截器logger和security,如下:

<package name="default" extends="struts-default">
    <interceptors>
        <!-- 定义名为logger的拦截器-->
        <interceptor name="logger" class="org.sunxin.interceptor.LogInterceptor" />
        <!-- 定义名为security的拦截器-->
        <interceptor name="security" class="org.sunxin.interceptor.ValidationInterceptor" />
    </interceptors>
    <action name="resource" class="org.sunxin.action.ResourceAction">
        <result name="input">login.jsp</result>
        <result>resource.jsp</result>
        <!-- 为resource action指定拦截器引用,当resource action被调用时,logger和security拦截器也会被调用 -->
        <interceptor-ref name="logger" />
        <interceptor-ref name="security" />
    </action>
</package>

拦截器按照action引用拦截器的顺序执行,如果一个action需要多个拦截器,一一引用比较麻烦,可以将多个拦截器组合在一起,组成一个拦截器栈,然后在action中直接引用拦截器,例如:

<package name="default" extends="struts-default">
    <interceptors>
        <!-- 定义名为logger的拦截器-->
        <interceptor name="logger" class="org.sunxin.interceptor.LogInterceptor" />
        <!-- 定义名为security的拦截器-->
        <interceptor name="security" class="org.sunxin.interceptor.ValidationInterceptor" />
    </interceptors>
    <interceptor-stack name="loggerAndSecurityStack" >
        <interceptor-ref name="logger" />
        <interceptor-ref name="security" />
    </intercetpor-stack>
    <action name="resource" class="org.sunxin.action.ResourceAction">
        <result name="input">login.jsp</result>
        <result>resource.jsp</result>
        <interceptor-ref name="loggerAndSecurityStack" />
    </action>
</package>

在引用拦截器时,struts2并不区分拦截器和拦截器栈,所以我们在定义拦截器栈时也可以引用其他的拦截器栈。
如果多个action都需要引用相同的拦截器,那么我们可以使用default-interceptor-ref元素来定义一个默认的拦截器或拦截器栈引用,这样就不需为每个action指定引用信息了。例如:

<package name="default" extends="struts-default">
    <interceptors>
        <!-- 定义名为logger的拦截器-->
        <interceptor name="logger" class="org.sunxin.interceptor.LogInterceptor" />
        <!-- 定义名为security的拦截器-->
        <interceptor name="security" class="org.sunxin.interceptor.ValidationInterceptor" />
    </interceptors>
    <interceptor-stack name="loggerAndSecurityStack" >
        <interceptor-ref name="logger" />
        <interceptor-ref name="security" />
    </intercetpor-stack>
    <!-- 定义默认的拦截器栈引用-->
    <default-intercetpor-ref name="loggerAndSecurityStack">
    <!-- resource action将使用默认拦截器栈引用 -->
    <action name="resource" class="org.sunxin.action.ResourceAction">
        <result name="input">login.jsp</result>
        <result>resource.jsp</result>
    </action>
</package>

要注意的是,如果在一个action中定义了其他的拦截器引用,那么这个action将不再使用默认拦截器引用,例如:

<package name="default" extends="struts-default">
    <interceptors>
        <!-- 定义名为logger的拦截器-->
        <interceptor name="logger" class="org.sunxin.interceptor.LogInterceptor" />
        <!-- 定义名为security的拦截器-->
        <interceptor name="security" class="org.sunxin.interceptor.ValidationInterceptor" />
    </interceptors>
    <interceptor-stack name="loggerAndSecurityStack" >
        <interceptor-ref name="logger" />
        <interceptor-ref name="security" />
    </intercetpor-stack>
    <!-- 定义默认的拦截器栈引用-->
    <default-intercetpor-ref name="loggerAndSecurityStack">
    <!-- resource action将不再使用默认拦截器栈引用,而使用timer -->
    <action name="resource" class="org.sunxin.action.ResourceAction">
        <result name="input">login.jsp</result>
        <result>resource.jsp</result>
        <interceptor-ref name="timer" />
    </action>
</package>

如果action想要在默认拦截器引用的基础上添加新的拦截器,那么只能在action中重新配置默认拦截器引用中的拦截器

<action name="resource" class="org.sunxin.action.ResourceAction">
     <result name="input">login.jsp</result>
     <result>resource.jsp</result>
     <interceptor-ref name="timer" />
     <interceptor-ref name="loggerAndSecurityStack" />
</action>

下一篇,我们继续学习struts.xml关于action的配置

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐