Struts2:配置Action——包和命名空间

本文摘自 李刚 《Java EE 企业应用实战》

 

 

实现了Action处理类之后,就可以在struts.xml文件中配置该Action了。所谓配置Action就是指定让struts2的哪个Action处理哪个请求,也就是完成用户请求和Action之间的关系。我们可以认为struts2的基本“程序单位”。

 

一. 包

        Struts2使用包来组织Action,因此,将Action定义在包定义下完成,定义Action通过使用package下的action子元素来完成,而每个package元素配置一个包。

        Struts2框架中的核心组件就是Action拦截器,Struts2框架使用包来管理Action和拦截器等,每个包就是多个Action、多个拦截器、多个拦截器引用的集合。

        配置package元素是必须指定name属性,这个属性是引用该包的唯一标识,除此之外,还可以指定一个可选的extends属性,extends属性必须是另一个包的name属性。指定extends属性表示让该包继承另一个包,子包可以从一个或者多个父包中继承到拦截器、拦截器栈、action等配置。

       除此之外,Action2还提供了一种所谓的抽象包,抽象包的意义是该报不能包含Action的定义。为了显示指定一个包是抽象包,可以为该package元素增加一个abstract = "true"属性。

       在struts.xml文件中,package 元素用于定义包配置,每个package元素定义一个包配置,定义package时可以指定如下几个属性:

       (1) name: 这是一个必须的属性,该属性指定该包的名字,该名字是该包被其他包引用的key。

       (2) extends: 该属性是一个可选属性,该属性指定该报继承其他包。继承其他包,就可以继承其他包中的Action定义、拦截器定义等。

       (3) namespace: 该属性是一个可选属性,该属性定义该包的命名空间。

       (4) abstract: 该属性是一个可选属性,他指定该包是否是一个抽象包,在抽象包中不能有package属性。

        因为Struts2的配置文件时从上到下进行处理,所以父包应该在子包的前面定义。

        下面是一个简单的struts.xml文件配置文件范例。在下面的struts.xml文件中配置两个包,其中名为default的包,继承了Struts2框架的默认包:struts-default。

[html]  view plain copy
  1. <?xml version = "1.0" encoding = "UTF-8"?>  
  2.     <!--下面是Struts2配置文件的DTD信息 -->    
  3. <!DOCTYPE struts PUBLIC    
  4.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    
  5.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  6.     <!--struts是struts2配置文件的跟元素 -->  
  7. <struts>  
  8.     <!--配置第一个包,该包名为default,继承了struts-default-->  
  9.     <!--package元素是struts配置文件的核心,该元素可以出现0次,或者是无限多次 -->  
  10.     <package name="default" extends="struts-default">  
  11.         <!--下面定义了拦截器部分-->  
  12.         <!--以下的该元素可以出现,也可以不出现,但最多出现1次 -->  
  13.         <interceptors>  
  14.             <!--定义拦截器栈-->  
  15.             <!--下面的元素可以出现0次,也可以出现无限多次 -->  
  16.             <interceptor-stack name="crudeStack">  
  17.                 <!-- 下面的元素必须出现,可以出现无数多次 -->  
  18.                 <interceptor-ref name="params" />  
  19.                 <interceptor-ref name="defaultStack" />  
  20.             </interceptor-stack>  
  21.         </interceptors>  
  22.         <!-- 下面的元素可以出现0次,也可以出现无限多次 -->  
  23.         <default-action-ref name="showcase" />  
  24.         <!--定义一个Action,该Action直接映射到showcase.jsp页面-->  
  25.         <action name="showcase" class="" method="" convertor="">  
  26.             <!-- 下面的元素可以出现0次,也可以出现无限多次 -->  
  27.             <param name="参数名">参数值</param>  
  28.             <!-- 下面的元素可以出现0次,也可以出现无限多次 -->  
  29.             <result>showcase.jsp</result>  
  30.         </action>  
  31.         <!--定义一个Action,该Action类为lee.DateAction-->  
  32.         <action name="Date" class="lee.DateAction">  
  33.             <result name="success">/date.jsp</result>  
  34.         </action>  
  35.     </package>  
  36.   
  37.     <!--定义一个名为skill的包,该包直接继承default的包-->  
  38.     <package name="skill" extends="default" namespace="/skill">  
  39.         <!--定义默认的拦截器引用-->  
  40.         <default-interceptor-ref name="crudeStack" />  
  41.         <!--定义一个名为Edit的Action,该Action对应的处理类是lee.SkillAction-->  
  42.         <action name="edit" class="lee.SkillAction">  
  43.             <result>/empmanager/editskill.jsp</result>  
  44.             <interceptor-ref name="params" />  
  45.             <interceptor-ref name="basicStack" />  
  46.         </action>  
  47.         <!--定义一个名为Save的Action ,该Action对应的处理类lee.SkillAction,使用skill方法作为处理方法-->  
  48.         <action name="Save" class="lee.SkillAction">  
  49.             <result name="input">/empmanager/editSkill.jsp</result>  
  50.             <result name="redirect">edit.action?skillName=${currentSkill.name}  
  51.             </result>  
  52.         </action>  
  53.     </package>  
  54. </struts>    

        上面的struts.xm文件中第一个package中定义继承了一个struts-default父包,那这个父包位于何处呢?其实它位于struts核心jar包struts2-core-2.x.x.jar文件中,只要解压该文件就能看到一个struts-default.xml文件。

        从上面的配置片段就可以看出,struts2-core-2.x.x.jar里已经定义了struts-default抽象包,该包下包含了大量的结果类型定义、拦截器定义、拦截器引用定义等,这些定义是配置普通Action的基础,所以开发者的package通常应该继承于struts-default包。

        注意:实际上所有struts2插件文件都会提供一个struts-plugin.xml文件,而不同的struts-plugin.xml文件会定义另一个抽象包,用于被需要使用该插件的开发者继承,所以如果我们使用struts2中的某个插件时,可能需要用到struts插件文件中的包。

 

二. 命名空间

        从前面的内容可知,每定义一个package元素时,都可以指定一个namespace属性,用于指定该包对应的命名空间。

        Struts2只所以提供命名空间的功能,主要是为了处理同一个web应用中包含同名的Action的情形,Struts2以命名空间方式来管理Action,同一个命名空间中不能有相同的Action,不同的命名空间中可以有不同的Action。

        Struts2不支持为单独的Action设置命名空间,而是通过包指定namespace属性来为包下面的所有Action指定共同的命名空间。如果配置package时没有指定namespace属性,那么包下的所有Action处于默认的包空间下。

        下面用一个应用示例来说明Struts2的命名空间的用法。看下面的struts.xml文件中的代码这份配置文件中配置两个package,并为后一个package指定了命名空间为/book。

[html]  view plain copy
  1. <?xml version = "1.0" encoding = "UTF-8"?>  
  2.     <!--下面是Struts2配置文件的DTD信息 -->    
  3. <!DOCTYPE struts PUBLIC    
  4.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    
  5.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  6.     <!--struts是struts2配置文件的跟元素 -->  
  7. <struts>  
  8. <!--配置国际化资源常量,指定国际化资源文件的baseName为messageResource-->  
  9. <!--下面的元素可以出现0次,也可以出现无限多次 -->    
  10.     <constant name="struts.custom.i18n.resource" value="messageResource"/>    
  11.     <!--配置名为lee的包,该包继承了struts2的默认包,没有指定命名空间,将使用默认命名空间-->  
  12.     <!--package元素是struts配置文件的核心,该元素可以出现0次,或者是无限多次 -->  
  13.     <package name="lee" extends="struts-default">  
  14.   
  15.         <!--配置一个名为Login的Action-->  
  16.         <action name="login" class="lee.LoginAction">  
  17.           <result name ="input">/login.jsp</result>  
  18.             <result name ="error">/error.jsp</result>  
  19.             <result name = "success">/success.jsp</result>  
  20.         </action>  
  21.     </package>  
  22. <!--配置名为get的包,该包继承了struts2的默认包,指定该包的命名空间为/book-->  
  23.     <!--package元素是struts配置文件的核心,该元素可以出现0次,或者是无限多次 -->  
  24.     <package name="get" extends="struts-default" namespace = "/book">  
  25.         <!--配置一个名为getBooks的Action-->  
  26.         <action name="getBooks" class="lee.GetBooksAction">  
  27.           <result name ="input">/login.jsp</result>  
  28.             <result name = "success">/success.jsp</result>  
  29.         </action>  
  30.     </package>  
  31. </struts>    

       在上面的struts.xml配置文件,配置两个包:lee和get,配置get包时namespace属性配置包的命名空间属性为/books

       对于名为lee的包而言,该包没有指定namespace属性。如果该包没有指定namespace属性那么该包使用默认的命名空间,默认空间名总是" "。

       当某个包指定了命名空间后,该包下所有的Action处理的URL应该是命名空间+Action名。以上面的代码中get包为例,该包下包含了名为getBooks的Action,该Action处理的URL为:

[html]  view plain copy
  1. http://localhost:8080/namespace/book/GetBooks.action  

      注意:Struts2中的命名空间的作用等同于Struts1中的模块的作用,它允许以模块化的方式来组织Action。

      除此之外,Struts2还可以显示指定根命名空间,通过设置某个包的namespace = "/"来指定根命名空间。

       (1) 具体路径命名空间和默认命名空间

        如果请求为/barspace/bar.action,系统首先查找/barspace命名空间里名为bar的Action,如果在该命名找到对应的Action,则使用该Action处理用户的请求;否则,系统将到默认的命名空间中查找名为bar的Action,如果找到对应的Action,则使用该Action处理用户的请求;如果两个命名空间里都找不到名为bar的Action,则系统将出现错误。

      注意:默认的命名空间里的Action可以处理任何命名空间下的Action请求。意思就是说,如果存在URL为/barspace/bar.action的请求,并且/barspace的命名空间下没有名为bar的Action,则默认命名空间下名为bar的Action也会处理用户的请求。但是根命名空间下的Action只处理根命名空间下的请求,这就是根命名空间和默认命名空间的区别。

 

       (2) 根命名空间和系统默认命名空间

        如果请求为/login.action,系统会根据根命名空间("/")中查找名为login的Action,如果在根命名空间中找到了名为login的Action,则该Action处理用户的请求;否则系统将转为在默认命名空间中寻找名为login的Action,如果默认的命名空间中有名为login的Action,则由该Action处理用户的请求。如果两个命名空间中都找不到名为login的Action,那么系统将出现错误。

      注意:命名空间只有一个级别。如果请求的URL是/bookservice/search/get.action系统将先在/bookservice/search的命名空间下查找名为get的Action,如果在该系统命名空间内找到名为get的Action,则由该Action处理该用户的请求;如果在该命名空间中没有找到名为get的Action,系统将直接进入默认的命名空间中查找名为get的Action,而不会在bookservice的命名空间下查找名为get的Action。

你可能感兴趣的:(Struts2:配置Action——包和命名空间)