玩技术,Geeker
一个原创技术文章分享网站

Struts2学习之Action的通配符使用

这么冗余的代码

在这篇《Struts2学习之配置单个Action多控制处理逻辑》文章中,讲到指定method属性时,列举了以下的配置代码:

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />

    <package name="lee" extends="struts-default" namespace="/">
        <action name="loginAction" class="com.jellythink.practise.LoginAction" method="login">
            <result name="input">/login.jsp</result>
            <result name="error">/error.jsp</result>
            <result name="success">/success.jsp</result>
        </action>

        <action name="registAction" class="com.jellythink.practise.LoginAction" method="regist">
            <result name="regist">/regist.jsp</result>
        </action>
    </package>
</struts>

可以发现,上面配置的两个Action,有很大一部分是类似的,存在冗余的现象。在Struts2框架中,允许使用通配符的方式进行配置。下面就利用Struts2框架的这一特性对上述这段配置代码进行重构。

重构第一步

在配置<action .../>元素时,允许在指定name属性时使用模式字符串(即用“*”代表一个或多个任意字符),接下来就可以在class、method属性及<result .../>子元素中使用{N}的形式来代表前面第N个星号所匹配的子串。基于此,文章一开始的配置代码可以重构为以下这样:

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />

    <package name="lee" extends="struts-default" namespace="/">
        <action name="*Action" class="com.jellythink.practise.LoginAction" method="{1}">
            <result name="input">/{1}.jsp</result>
            <result name="error">/error.jsp</result>
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

上面的<action name="*Action" .../>元素不是定义了一个普通Action,而是定义了一系列的逻辑Action。只要用户请求的URL是*Action.action的模式,都可以使用该Action来处理。配置该action元素时,还指定method属性,但该method属性使用了一个表达式{1},该表达式就是name属性值中第一个*的值。例如:如果用户请求的URL为loginAction.action,则调用对应的login方法;如果为registAction.action,则调用regist方法。对于<result .../>子元素中使用的/{1}.jsp也是同样的道理。

重构第二步

更多时候,我们希望action对应的class属性也可以进行模式匹配,这样的话灵活性更高。比如现在有两个Action类,分别为:com.jellythink.practise.LoginActioncom.jellythink.practise.RegistAction,这两个类分别完成登陆与注册行为。当action的name匹配到loginAction时,则对应的class则为com.jellythink.practise.LoginAction;当匹配到registAction时,则对应的clas则为com.jellythink.practise.RegistAction。按照这样的需求,上述的配置代码又可以修改为这样:

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />

    <package name="lee" extends="struts-default" namespace="/">
        <action name="*_*" class="com.jellythink.practise.{1}Action" method="{2}">
            <result name="input">/{2}.jsp</result>
            <result name="error">/error.jsp</result>
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

在上述配置代码中,action的name属性为*_*,这需要我们在前台页面设置action的值时按照指定的规则进行设定,例如:类名_方法名。当用户请求的URL是Login_login.action的模式时,则{1}代表的值为Login,而对应的{2}代表的值为login;同理,当请求为Regist_regist.action的模式时,则{1}代表的值为Regist,而对应的{2}代表的值为regist。

通过这种方式,配置代码的灵活性更高,写法更简单。

到底使用哪个?

通过使用模式匹配的方式,就会引申出另一个问题。比如有下面这段配置代码:

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />

    <package name="lee" extends="struts-default" namespace="/">
        <!--Action1-->
        <action name="*Action" class="com.jellythink.practise.{1}Action" method="{1}">
            <result name="input">/{1}.jsp</result>
            <result name="error">/error.jsp</result>
            <result name="success">/success.jsp</result>
        </action>

        <!--Action2-->
        <action name="getBookInfoAction" class="com.jellythink.practise.GetBookInfoAction">
            <result name="error">/error.jsp</result>
            <result name="success">/success.jsp</result>
        </action>

        <!--Action3-->
        <action name="*" class="com.jellythink.practise.DefaultAction">
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

问题是,如果客户端请求的URL是getBookInfoAction.action,那么到底匹配哪个Action呢?对于Struts2框架来说,规则是这样的:

  • 如果请求URL是getBookInfoAction.action,如果struts.xml文件中有名为getBookInfoAction的Action配置,则一定由该Action来处理用户请求
  • 如果struts.xml文件中没有名为getBookInfoAction的Action配置,则搜寻name属性值能匹配getBookInfoAction的Action,例如name为Action或,*Action并不会比*更优先匹配getBookInfoAction的请求,这取决于这两个Action定义的先后顺序

总结

在日后的工作中,使用这样的技巧来重构代码,会带来很多好处,比如配置代码更加精简了,更加容易管理和维护了,更加容易读懂了等等。如果你说你不想用这些东西,那也好,至少你需要知道有这么个东西的存在,好让你去读懂别人写的代码。

学习总是乏味无趣。
果冻想-一个原创技术文章分享网站。

2016年2月21日 于呼和浩特。

打赏

未经允许不得转载:果冻想 » Struts2学习之Action的通配符使用

分享到:更多 ()

评论 2

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    好久没来,过来踩踩~

    cloudxiao1年前 (2016-06-14)回复

在这里玩技术,享受技术带来的疯狂

捐赠名单关于果冻