首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

《研磨struts2》第四章 Action 之 4.4 Action的配备

2012-07-02 
《研磨struts2》第四章 Action 之 4.4 Action的配置4.4? Action的配置4.4.1? package的配置通过上面的示例

《研磨struts2》第四章 Action 之 4.4 Action的配置

4.4? Action的配置

4.4.1? <package>的配置

通过上面的示例可以看出,Action需要在struts.xml中配置才可以使用,而且Action应该配置成为<package>元素的子元素,那么<package>元素的功能是什么呢?

?????? <package>元素可以把逻辑上相关的一组Action、Result、Intercepter等元素封装起来,形成一个独立的模块,package可以继承其他的package,也可以作为父包被其他的package继承,比如前面示例中配置的“<package name="helloworld"? extends="struts-default">”,helloworld这个包就继承了struts-default这个包。

?????? <package>元素有如下属性:

  • name:包的名称。必须配置
  • extends:要继承的包,后面配置的是被继承的包的名称。可选
  • namespace:包的命名空间。可选
  • abstract:定义包为抽象的,也就是不能包含Action的定义。可选

    上面的属性中name和extends在前面已经示例过了,接下来看看另外两个属性的应用。

    1:namespace

    namespace配置的是包的命名空间,同一个命名空间里面不能有同名的Action,当然不同的命名空间里面是可以有同名的Action的。类似于Java的包的功能,namespace可以有效的防止action重名的冲突,因为配置了namespace后,在访问action的时候就需要添加namespace来作为action的前缀。

    如果不配置namespace,表示是默认的namespace,那么访问的时候不需要添加namespace前缀。比如前面HelloWorld的示例,struts.xml的配置如下:

    ?

    java代码:查看复制到剪贴板打印
    1. <?xml?version="1.0"?encoding="UTF-8"??>??
    2. <!DOCTYPE?struts?PUBLIC??
    3. ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
    4. ????"http://struts.apache.org/dtds/struts-2.0.dtd">??
    5. ??
    6. <struts>??
    7. ????<constant?name="struts.devMode"?value="true"?/>??
    8. ????<constant?name="struts.locale"?value="zh_CN"/>??
    9. ????<constant?name="struts.i18n.encoding"?value="gb2312"/>??
    10. ??
    11. ????<package?name="helloworld"??extends="struts-default">??
    12. ????????<action?name="helloworldAction"?class="cn.javass.hello.struts2impl.action.HelloWorldAction">??
    13. ????????????<result?name="toWelcome">/s2impl/welcome.jsp</result>??
    14. ????????</action>??
    15. </package>??
    16. </struts>??

    观察里面加粗的那句,也就是<package>元素的定义,里面是没有配置namespace的,因此在访问的时候,是直接在webcontext下面写要访问的action的名称的,示例如下:

    ?

    java代码:查看复制到剪贴板打印
    1. <form?action="/helloworld/helloworldAction.action"?method="post">??
    2. ????……??
    3. </form>??

    其中“/helloworld”是webcontext。

    如果配置了namespace,那么访问的时候是必须要添加namespace前缀的,配置namespace的时候“/”表示namespace的根。示例如下:

    ?

    java代码:查看复制到剪贴板打印
    1. ……省略了??
    2. <package?name="hello"?namespace="/javass"?extends="struts-default">??
    3. ????????<action?name="helloworldAction"?class="cn.javass.hello.struts2impl.action.HelloWorldAction">??
    4. ????????????<result?name="toWelcome">/s2impl/welcome.jsp</result>??
    5. ????????</action>??
    6. </package>??

    那么访问的时候就需要加上namespace,示例如下:

    ?

    java代码:查看复制到剪贴板打印
    1. <form?action="/helloworld/javass/helloworldAction.action"?method="post">??
    2. ????……??
    3. </form>??

    2:abstract

    abstract用来定义包为抽象的,也就是不能包含Action的定义,但是抽象包可以被其他包继承,因此里面可以定义其他包需要的元素,比如ResultType、Interceptor等等。

    比如上面HelloWorld示例中继承的struts-default包,它就是个抽象的包,定义示例如下:

    ?

    java代码:查看复制到剪贴板打印
    1. <package?name="struts-default"?abstract="true">??
    2. ????……??
    3. </package>??

    4.4.2? <action>的配置

    虽然Action在Struts2的开发中非常重要,但是其配置非常简单,基本的规则如下:

    • <action>元素是<package>元素的子元素,应该配置在<package>元素里面
    • <action>元素通常需要配置name和class属性,其中name是必须的
    • <action>元素可以包含其他的子元素:比如<param>、<result>、<interceptor-ref>、<exception-mapping >

      基本的配置示例前面已经有了,通常也就是配置name和class属性,然后配置<result>子元素,这里就不去赘述,而更多的配置在后面用到再讲。

      4.4.3? 分模块配置方式

      -??l:8? ` o-ascii-font-family:"Times New Roman"; mso-hansi-font-family:"Times New Roman"'>虽然Action在Struts2的开发中非常重要,但是其配置非常简单,基本的规则如下:

      ?

      • <action>元素是<package>元素的子元素,应该配置在<package>元素里面
      • <action>元素通常需要配置name和class属性,其中name是必须的
      • <action>元素可以包含其他的子元素:比如<param>、<result>、<interceptor-ref>、<exception-mapping >

        基本的配置示例前面已经有了,通常也就是配置name和class属性,然后配置<result>子元素,这里就不去赘述,而更多的配置在后面用到再讲。

        在多人协作开发的团队中,配置文件如何组织至关重要。如果配置文件过少,会出现多人争用一个文件,造成大家互相等待,影响开发效率。如果配置文件过多,动辄几十上百个配置文件,这也会造成维护的困难,从而影响到开发的效率。

        ?????? 因此,如何划分配置文件的大小就显得尤为重要。在Struts2的开发中,struts.xml这个配置文件就是大家经常争用的核心配置。

        ?????? 通常,一个项目会根据业务的不同来划分出不同的模块,一个模块会由几个人协作开发,在模块内大家联系紧密,但是在模块间相互联系就会比较松散。因此,在划分配置文件的时候,一种常见的情况就是按照模块来划分。

        (1)现在,简单回顾一下HelloWorld中的struts.xml。

        margin-Lo:8? ` argin-left:42.5pt'>????????? <action>元素通常需要配置name和class属性,其中name是必须的

        ?

        • <action>元素可以包含其他的子元素:比如<param>、<result>、<interceptor-ref>、<exception-mapping >

          基本的配置示例前面已经有了,通常也就是配置name和class属性,然后配置<result>子元素,这里就不去赘述,而更多的配置在后面用到再讲。

          ?

          java代码:查看复制到剪贴板打印
          1. <?xml?version="1.0"?encoding="UTF-8"??>??
          2. <!DOCTYPE?struts?PUBLIC??
          3. ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
          4. ????"http://struts.apache.org/dtds/struts-2.0.dtd">??
          5. <struts>??
          6. ????<constant?name="struts.devMode"?value="true"?/>??
          7. ????<constant?name="struts.locale"?value="zh_CN"/>??
          8. ????<constant?name="struts.i18n.encoding"?value="gb2312"/>??
          9. ??
          10. <package?name="helloworld"??extends="struts-default">??
          11. ????<action?name="helloworldAction"?class="cn.javass.hello.struts2impl.action.HelloWorldAction">??
          12. ????????<result?name="toWelcome">/s2impl/welcome.jsp</result>??
          13. ????</action>??
          14. </package>??
          15. </struts>??

          ?

          java代码:查看复制到剪贴板打印
          1. 这个配置文件的根元素是<struts>,它下面有三个<constant>常量配置元素和一个<package>元素,而一个<package>元素下有一个<action>元素。现在关心的是action在项目中如何划分,所以抛开<constant>常量配置元素不看。其余的元素之间关系是:??
          2. ????一个<struts>元素可以有多个<package>子元素。??
          3. ????一个<package>元素可以有多个<action>子元素。??
          4. ????按照项目的组织形式来类比,这里的<struts>元素就好比代表项目,而<package>元素就是好比是业务模块,而<action>元素就相当于是某个模块中的组件。??
          5. 这样一来,就可以按照业务模块来组织我们的action了,也就是同一个模块的action配置在同一个包里面。??
          6. ????由于一个项目会有多个业务模块,也就是会有多个<package>,如果所有的<package>都配置在一个struts.xml文件里面,必然会引起大家争用这个配置文件,因此,在实际开发中,通常都是一个<package>放在一个单独的文件中,比如叫struts-xxx.xml,最后由struts.xml来引用这些struts-xxx.xml。??
          7. (2)比如一个电子商务的项目,分成饭店管理模块和入境管理模块。那么,饭店管理模块会单独有一个struts-hotel.xml,而入境管理模块会单独有一个struts-inbound.xml,最后由struts.xml来引用它们。??
          8. ????此时struts.xml的代码示例如下:??

          ?

          java代码:查看复制到剪贴板打印
          1. <?xml?version="1.0"?encoding="UTF-8"??>??
          2. <!DOCTYPE?struts?PUBLIC??
          3. ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
          4. ????"http://struts.apache.org/dtds/struts-2.0.dtd">??
          5. <struts>??
          6. ????<constant?name="struts.devMode"?value="true"?/>??
          7. ????<constant?name="struts.locale"?value="zh_CN"></constant>??
          8. ????<constant?name="struts.i18n.encoding"?value="gb2312"></constant>??
          9. ??????
          10. ????<include?file="struts-hotel.xml"></include>??
          11. ????<include?file="struts-inbound.xml"></include>??
          12. </struts>??

          此时struts-hotel.xml的代码示例如下:

          ?

          java代码:查看复制到剪贴板打印
          1. <?xml?version="1.0"?encoding="UTF-8"??>??
          2. <!DOCTYPE?struts?PUBLIC??
          3. ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
          4. ????"http://struts.apache.org/dtds/struts-2.0.dtd">??
          5. <struts>??
          6. ????<package?name="hotel"?namespace="/hotel"?extends="struts-default">??
          7. ????????<action?name="bookingAction"?class="cn.javass.hotel.action.HotelBookingAction">??
          8. ????????????<result?name="success">/hotel/booking.jsp</result>??
          9. ????????</action>??
          10. ????????<action?name="queryAction"?class="cn.javass.hotel.action.QueryAction">??
          11. ????????????<result?name="success">/hotel/query.jsp</result>??
          12. ????????</action>??
          13. ????</package>??
          14. </struts>??

          此时struts-inbound.xml的代码示例如下:

          ?

          java代码:查看复制到剪贴板打印
          1. <?xml?version="1.0"?encoding="UTF-8"??>??
          2. <!DOCTYPE?struts?PUBLIC??
          3. ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
          4. ????"http://struts.apache.org/dtds/struts-2.0.dtd">??
          5. <struts>??
          6. ????<package?name="inbound"?namespace="/inbound"?extends="struts-default">??
          7. ????????<action?name="bookingAction"?class="cn.javass.inbound.action.BookingAction">??
          8. ????????????<result?name="success">/inbound/booking.jsp</result>??
          9. ????????</action>??
          10. ????????<action?name="queryAction"?class="cn.javass.inbound.action.QueryAction">??
          11. ????????????<result?name="success">/inbound/query.jsp</result>??
          12. ????????</action>??
          13. ????</package>??
          14. </struts>??

          4.4.4??使用通配符

          在以前的学习中,<action>元素的配置,都是用明确的配置,其name、class等属性都是一个明确的值。

          其实Struts2还支持class属性和method属性使用来自name属性的通配符,method属性是用来指示一个Action中的方法,这个方法会在执行Action的时候执行,也就是说,你配置了method属性,Action运行的时候会执行这个方法而不是execute方法,这个在后面会有详细讲述和示例。

          (1)接下来看看使用通配符的示例,如果我们使用以下<action>配置:

          ?

          java代码:查看复制到剪贴板打印
          1. <action?name="*_*"?class="cn.javass.action.action.{1}Action"?method="{2}">??
          2. ????????????<result?name="toWelcome">/s2impl/welcome.jsp</result>??
          3. </action>??

          在上面的配置中:

          ?????? name属性的值中“*”代表长度不为0的任意字符串,因此,它可以响应的action只需要名称中间有一个下划线即可。比如页面可访问的action名称为:HelloWorld_create.action、HelloWorld _update.action等等。

          ?????? 在name属性定义了通配符之后,class属性使用第一个通配符(使用{1}作为占位),method属性使用第二个通配符。

          ?????? 如果使用HelloWorld_create.action作为访问的action名称的话,struts.xml中action名称为HelloWorld_create,第一个通配符匹配HelloWorld,第二个通配符匹配create。因此,由cn.javass.action.action.HelloWorldAction的create方法来响应。

          ?????? 此时Action的实现,示例代码如下:

          ?

          java代码:查看复制到剪贴板打印
          1. package?cn.javass.action.action;??
          2. import?com.opensymphony.xwork2.ActionSupport;??
          3. public?class?HelloWorldAction?extends?ActionSupport?{??
          4. ????private?String?account;??
          5. ????private?String?password;??
          6. ????private?String?submitFlag;??
          7. ??????
          8. ????public?String?create(){??
          9. ????????System.out.println("哈哈,访问到create方法了,account="+account);??
          10. ????????return?"toWelcome";??
          11. ????}??
          12. ??????
          13. ????public?String?execute()?throws?Exception?{??
          14. ????????System.out.println("访问到execute方法了,account="+account);??
          15. ????????return?"toWelcome";??
          16. ????}??
          17. ????//属性对应的getter/setter方法,省略了??
          18. }??

          ? ? ? ?此时的登录页面,示例代码如下:

          ?

          java代码:查看复制到剪贴板打印
          1. <form?action="/helloworld/HelloWorld_create.action"?method="post">??
          2. ????<input?type="hidden"?name="submitFlag"?value="login"/>??
          3. ????账号:<input?type="text"?name="account"><br>??
          4. ????密码:<input?type="password"?name="password"><br>??
          5. ????<input?type="submit"?value="提交">??
          6. </form>??

          去测试运行看看,输出结果应该为:

          ?

          java代码:查看复制到剪贴板打印
          1. 哈哈,访问到create方法了,account=11??

          (2)在使用通配符的时候,也有可能不只一个使用通配符的<action>元素可能匹配这次URL的访问,看以下的配置文件:

          ?

          java代码:查看复制到剪贴板打印
          1. <action?name="HelloWorld_create"?class="cn.javass.action.action.HelloWorldAction"?method="create2">??
          2. ????????????<result?name="toWelcome">/s2impl/welcome.jsp</result>??
          3. ????????</action>??
          4. <action?name="*_*"?class="cn.javass.action.action.{1}Action"?method="{2}">??
          5. ????????????<result?name="toWelcome">/s2impl/welcome.jsp</result>??
          6. </action>??

          这时候,如果访问“/helloworld/HelloWorld_create.action”,Struts2首先会查找是否有精确匹配的<action>元素,这时候无论以上<action>元素以什么顺序出现,Struts2肯定会先找到并使用精确匹配的<action>元素。但是,如果没有精确匹配的<action>元素,则Struts2会找到第一个匹配的使用通配符的<action>元素来使用。

          ?????? 通配符对于那些简单的CRUD的工程或软件原型来说,只要Action的包名、Action的类名、对应的方法名写的有规律的应用,能大大简化配置的工作。

          4.4.5? 默认类配置方式

          -??-a8? ` es New Roman";mso-hansi-font-family: "Times New Roman"'>元素,则Struts2会找到第一个匹配的使用通配符的<action>元素来使用。

          ?

          ?????? 通配符对于那些简单的CRUD的工程或软件原型来说,只要Action的包名、Action的类名、对应的方法名写的有规律的应用,能大大简化配置的工作。

          4.4.5??默认类配置方式

          在配置struts.xml的时候,对于<action>元素来说,name属性是必须的,class属性是可以省略的,class属性的默认值是“com.opensymphony.xwork2.ActionSupport”。

          以前配置的<action>元素都是有class属性的,现在就来探究一下为什么可以不写class属性,以及在什么情况下可以不写。

          1:为何可以不配置<action>的class属性呢?

          在HelloWorld中, <package>元素的extends属性配置的是“struts-default”,说明了这个包继承了一个叫“struts-default”的包,这个包是真实存在的。可以到struts2-core-2.1.8.1.jar包的根目录下,找到一个叫“struts-default.xml”文件,这是Struts2默认配置好的各个<package>元素的公用配置。

          打开它,可以发现这个文件类似于我们熟悉的struts.xml。根元素也是<struts>,<struts>元素下面有一个子元素<package>,这个<package>的name属性的值正是“struts-default”。前面名为helloworld的<package>正是继承自这个struts-default包。在这里,我们并不详细展开讲解struts-default包,只是看最后的配置<default-class-ref />,这就说明了,<action>元素不写class属性的时候,默认配置就是使用ActionSupport类。

          2:有什么用呢

          ?????? 可能有朋友会想,这种做法有什么用呢?

          大多数情况下都是需要配置<action>的class属性的值的,因为我们需要把自己写的,用来处理请求的Action类配置上去,而不是使用默认的配置。确实是这样,但是这种默认类配置的方式在某些情况还是有用的。

          考虑这样一种情况,在实际开发中,对安全性要求较高的web项目,往往把jsp放在WEB-INF文件夹中,这样可以防止外界直接通过URL来访问jsp页面,这时的jsp就一定要是Servlet或Action的后继页面,才可以被访问到了。

          ?????? 因此,如果我们有一个jsp页面在WEB-INF下,但是在它之前不需要Action访问逻辑层,就相当于需要直接访问这个jsp页面。就可以让这个jsp作为ActionSupport的后继页面,使用default-class-ref,可以减少重复配置,示例配置如下:

          ?

          java代码:查看复制到剪贴板打印
          1. <action?name="test4">??
          2. <result>/WEB-INF/jsp/test4/1.jsp</result>??
          3. </action>??

          ActionSupport类的execute方法返回字符串“success”,而<result>元素的name属性如果不写的话,默认就是“success”。

          ?????? 这时候,访问http://localhost:9080/helloworld/helloworld/test4.action,就相当于是直接访问WEB-INF下的/jsp/test4/1.jsp。

          ?

          私塾在线网站原创《研磨struts2》系列

          转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4048.html】

          欢迎访问http://sishuok.com获取更多内容

热点排行