`

《研磨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 class="com.opensymphony.xwork2.ActionSupport" />,这就说明了,<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获取更多内容

分享到:
评论
6 楼 hunanjun000 2014-09-28  
   
5 楼 rongmiao 2013-01-16  
不太喜欢通配符的配置方式,虽然简单但是不是很灵活,权限什么的无法精细控制,另外不是很直观,虽然写的很少,但是看起来更累。
4 楼 wolfmaster 2012-10-30  
嘻嘻嘻休息休息
3 楼 wolfmaster 2012-10-30  
wolfmaster 写道
wolfmaster 写道
不错,不错,不错

很好

真的很好。。
2 楼 wolfmaster 2012-10-30  
wolfmaster 写道
不错,不错,不错

很好
1 楼 wolfmaster 2012-10-30  
不错,不错,不错

相关推荐

    研磨Struts2配书视频对应的演示源代码

    2. **拦截器(Interceptors)**:Struts2的核心之一是其拦截器机制,它们在Action执行前后执行一系列预定义或自定义的操作。这些拦截器可以用于登录验证、日志记录、性能监控等。源代码中可能包含了不同类型的拦截器...

    研磨Struts2

    - **Action类**:Action是Struts2的核心组件之一,负责处理用户的请求。本节将详细讲解Action类的设计原则和实现方法。 - **配置文件**:struts.xml用于配置Action的映射关系以及其他一些设置。本节将详细介绍如何...

    研磨struts2 高清版

    由于文件较大,我把这个文档切割为2部分,这是第一部分,请下载完第一部分后一定要下载第二部分,否则不能阅读。

    研磨Struts2配书视频对应的PPT

    PPT通常会包含关键概念的总结,如Action、Result、Interceptor、ValueStack等核心组件,以及Struts2配置文件的解析和使用。Action是业务逻辑的入口点,Result则负责视图的转发或重定向,Interceptor是Struts2的拦截...

    《研磨Struts 2》PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一份关于《研磨Struts 2》书籍PDF版本的下载资源。为了更好地理解和概括这份资料所涉及的知识点,我们先来了解一下Struts 2框架及其重要性,然后深入探讨《研磨Struts 2》这...

    研磨struts

    《研磨Struts2》这本书主要介绍了Struts2的基础知识、实践应用以及其核心概念。 1. **MVC模式**:MVC是一种设计模式,用于分离应用程序的业务逻辑、数据和用户界面。在Struts2中,Action类代表Controller,负责处理...

    研磨Struts2 高清完整版.part2

    研磨Struts2 高清完整版,请和第一部分一起下载啊

    研磨Struts2_12859679_高清完整版.part2.rar

    研磨Struts2_12859679_高清完整版

    研磨Struts2-高清-完整目录-2011年10月

    研磨Struts2-高清-完整目录-2011年10月,分享给所有需要的人

    研磨设计模式(完整带书签).part2.pdf

    第4章 适配器模式(Adapter) 第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章...

    研磨设计模式-part2

    第4章 适配器模式(Adapter) 第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章...

    Java工程师三大框架面试题.pdf

    Java工程师三大框架面试题.pdf

    研磨设计模式.part2(共4个)

    第4章 适配器模式(Adapter) 第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) ...

    研磨设计模式(完整带书签).part1.pdf

    第4章 适配器模式(Adapter) 第5章 单例模式(Singleton) 第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章...

Global site tag (gtag.js) - Google Analytics