`
CshBBrain
  • 浏览: 639343 次
  • 性别: Icon_minigender_1
  • 来自: 成都
博客专栏
B7d9bf34-126e-301f-819e-81f2615b5a2a
开源WebSocket服务...
浏览量:142405
Group-logo
HTML5移动开发
浏览量:135741
社区版块
存档分类
最新评论

Struts2零配置的实现

阅读更多

                             Struts2零配置的实现
  作者:Jason S.H.Chen
  对于做J2EE应用系统的朋友来说,没有不知道struts的。对于struts相关的资料我就不再啰嗦。Google一把,一大堆资料。
用过struts的朋友都知道struts的配置文件;struts1需要配置文件,struts2也需要配置文件。对于使用struts的系统来说配置文件相当于就相当于一个人的灵魂。Struts 控制器通过读取struts配置文件的信息,完成将用户的请求转换为调用对应的处理类的处理方法,并完成页面导航的工作。
下面看看struts的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans> <!—formbean的配置  -- >
    <form-bean name="UserForm"  type="com.amigo.struts.form.user.UserForm" />
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
<action  <!—action的配置  -- >
                path="/userAction"   type="com.amigo.struts.action.UserAction"
                name="UserForm" scope="request"  validate = "false"  parameter="method" >
             <forward name="error" path="/user/error.jsp" />
                  <forward name="success" path="/user/success.jsp"/>
                   <forward name="add" path="/user/addUser.jsp"/>
                   <forward name="update" path="/user/updateUser.jsp"/>
                   <forward name="list" path="/user/userList.jsp"/>
</action>
</action-mappings>
<message-resources parameter="com.amigo.struts. ApplicationResources " />
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
<set-property property="stopOnFirstError" value="false" />
</plug-in>
</struts-config>

上面一段内容是struts1配置文件的样例;红色标示的formbean和action配置,则每个功能都有对应的这些内容。

下面我们在看看struts2配置文件的样例:
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>

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

    <package name="com.kay.struts2" extends="struts-default" namespace="/test">
        <interceptors>
            <interceptor name="timer" class="com.kay.timer"></interceptor>
            <interceptor name="logger" class="com.kay.logger"></interceptor>
            <!-- 定义拦截器栈 -->
            <interceptor-stack name="mystack">
                <interceptor-ref name="timer"></interceptor-ref>
                <interceptor-ref name="logger"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
       
        <default-interceptor-ref name="mystack"></default-interceptor-ref>
        <!-- 全局results配置 -->
        <global-results>
            <result name="input">/error.jsp</result>
        </global-results>
       

        <action name="hello" class="com.kay.struts2.Action.LoginAction">
            <interceptor-ref name="timer"></interceptor-ref>       
         <result name="success" type="dispatcher">/talk.jsp</result>

         <param name="url">http://www.sina.com</param>
        </action>

    </package>
</struts>
红色标注的action配置,对于每个action都有对应的配置。对于大型应用系统而言,struts的配置文件的内容将非常臃肿,感觉就是被淹没在了配置文件中。配置内容太多,不好维护是其一缺点,而根据struts的导航机制来看,配置内容太多对其性能也应该是有影响的(配置文件的内容在系统启动时加载到映射表中,struts在导航的时候到映射表中查找;内容越多,其性能肯定也好不了)。
好,说了这么多。那咱们来谈谈到底怎样来实现struts2的零配置方案呢。
1. 添加自己的struts.properties文件,在文件中添加如下内容:
struts.action.extension = action :表示请求添加action后缀,此项不是必须项

struts.enable.SlashesInActionNames = true : 允许在Action名中使用斜线

2. 封装一个基类,系统所有action都继承于这个基类;根据笔者多年做架构的经验,你还可以将更多通用处理的东西封装在基类中,以减少具体类的重复代码。基类可如下:
public class MyAction extends ActionSupport implements ApplicationContextAware{   
protected final static String JSPPAGE = "jsppage";
protected String target;
/**
*
* <li>方法名:renderJSPPage
* <li>@param _target 系统返回的JSP文件名。
* <li>@return 导航到jsp页面,返回JSPPAGE
* <li>返回类型:String
* <li>说明:参数为要返回的JSP页面名,系统自动导航到指定的页面。
* <li>创建人:Jason S.H.Chen
* <li>创建日期:2008-10-14
* <li>修改人:
* <li>修改日期:
*/
    public String renderJSPPage(String _target){  
        setTarget(_target);  
        return JSPPAGE;  
    }
   
    /**
     *
     * <li>方法名:getTarget
     * <li>@return 返回要导航到的页面。
     * <li>返回类型:String
     * <li>说明:这个函数一般不会手工调用到,框架中在配置文件中获取要导航
     * <li>到的文件名时,自动调用这个方法。
     * <li>创建人:Jason S.H.Chen
     * <li>创建日期:2008-10-14
     * <li>修改人:
     * <li>修改日期:
     */
    public String getTarget() {  
        return target;  
    }
    /**
     *
     * <li>方法名:setTarget
     * <li>@param target 需要导航到的页面名称。
     * <li>返回类型:void
     * <li>说明:程序要明确导航到某个页面,必须在代码中调用此函数进行设置要导航到的页面名称。
     * <li>创建人:Jason S.H.Chen
     * <li>创建日期:2008-10-14
     * <li>修改人:
     * <li>修改日期:
     */
    public void setTarget(String target) {  
        this.target = target;  
    }
}

所有继承于此类的子类,在他们的处理方法中调用renderJSPPage这个函数即实现了导航到指定的页面。
3. 配置文件的设置,说到这里有朋友可能要问了,你不是说零配置吗,为什么还提配置文件。我说的零配置不等于没有配置文件,我们这里对配置文件当中的内容设置一次,系统后面添加的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="struts2" extends="struts-default">
   
    <interceptors>
   
      <interceptor-stack name="myStack"> <!--- 我自定义了我的拦截器堆栈,你也可以使用他本身默认的-- >
    <interceptor-ref name="alias"/>

    <interceptor-ref name="servlet-config"/>

    <interceptor-ref name="prepare"/>

    <interceptor-ref name="i18n"/>

    <interceptor-ref name="chain"/>

    <interceptor-ref name="debugging"/>

    <interceptor-ref name="profiling"/>

    <interceptor-ref name="scoped-model-driven"/>

    <interceptor-ref name="model-driven"/>

    <interceptor-ref name="fileUpload"/>

    <interceptor-ref name="checkbox"/>

    <interceptor-ref name="static-params"/>

    <interceptor-ref name="params">

      <param name="excludeParams">dojo\..*</param>

    </interceptor-ref>

    <interceptor-ref name="conversionError"/>
   
    <interceptor-ref name="exceptionInterceptor"/>
    <interceptor-ref name="accessInterceptor"/>   
      </interceptor-stack>     
     
    </interceptors>
    <default-interceptor-ref name="myStack"/>   

<global-results> 
<result name="jsppage">${target}</result>

<result name="login">/index.jsp</result>
</global-results>
    </package>
   
    <constant name="struts.configuration.classpath.defaultParentPackage" value="struts2" />
</struts>
配置内容的关键:
<result name="jsppage">${target}</result> ,此处的name值必须为 jsppage,和我们封装基类的renderJSPPage函数中的返回值相同。${target} 的值为 renderJSPPage 方法中设置进来的jsp路径。
4. 将系统中的action的包路径设置在struts过滤器中
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
<init-param> 
    <param-name>actionPackages</param-name> 
    <param-value>
    com.company.systemname1.action,
    com.company.systemname2.action

    </param-value> 
   </init-param> 
</filter>
 
其中 actionPackages 参数中的值为系统所有action的包路径。系统启动时,struts会去扫描这些包下面的所有action.
写到这里基本上算是大功告成,你可以试试看。笔者在此有个建议,系统的基类其实还可以进一步封装,将到新增页面,编辑页面,查看页面和查询页面的方法进行抽象,进行默认导航。导航的规则和你系统开发时所定的命名规则以及文件的存放规则有关系,我想任何一个系统的开发都会对这些进行约束。那我们为什么不将这些命名规范写到基类里面,到达对程序员进行编码时进行约束呢,基类提供的这种规则审查,如果你用了,你将发现你可以节省很多代码审查的工作量量量。

参考资料:
struts2 配置的XML 详解:
http://blog.csdn.net/li285913050/archive/2008/04/02/2243321.aspx
struts2属性配置文件详解:
http://blog.csdn.net/xuchaofu/archive/2009/06/22/4287680.aspx

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics