首页 > 代码库 > Struts2-----6、配置Action

Struts2-----6、配置Action

(1)、包和命名空间

              Struts2用包来组织Action和拦截器等,每个包就是多个Action、拦截器、拦截器引用的集合;

              

<package.../>元素常用属性:

name:必须属性,指定该包的名字,让其他包引用的key

extends:指定该包继承其他包(另一个包的name属性:表示让该包继承另一包)(可继承其他包中的Action定义、拦截器定义等)

namespace:定义该包的命名空间

abstract:指定该包是否为一个抽象包(抽象包中不能包含Action定义)
父包应在子包前定义


struts.xml配置文件范例:

<struts>
    <package name="default" extends="struts-default">   
       <!-- 下面定义了拦截器部分 -->  
       <interceptors>
           <!-- 定义拦截器栈 -->
           <interceptor-stack name="crudStack">
              <interceptor-ref name="params" />
              <interceptor-ref name="defaultStack" />
           </interceptor-stack>
       </interceptors>
      
       <default-action-ref name="myAction" />   
      
       <!-- 定义一个Action,该Action直接映射到show.jsp页面 -->
       <action name="show">
           <result>show.jsp</result>
       </action>
        
       <action name="Date" class="org.crazyit.app.action.DateAction">
           <result name="success">/date.jsp</result>
       </action>
    </package>
   
    <!-- 继承default包 -->
    <package name="skill" extends="default" namespace="/skill">  
       <!-- 定义默认的拦截器引用 -->  
       <default-interceptor-ref name="crudStack" />
      
       <action name="Edit" class="lee.SkillAction">
           <result>/empmanager/editSkill.jsp</result>
           <interceptor-ref name="params" />  
           <interceptor-ref name="basicStack" />
       </action>
      
       <!-- 使用save方法作为处理方法 -->
       <action name="Save" class="lee.SkillAction" method="save">
           <result name="input">/empmanager/editSkill.jsp</result>
           <result type="redirect">edit.action?skillName=${currentSkill.name}</result>
       </action>
      
       <!-- 使用delte方法作为处理方法 -->
       <action name="Delete" class="lee.SkillAction" method="delete">
           <result name="error">/empmanager/editSkill.jsp</result>
           <result type="redirect">edit.action?skillName=${currentSkill.name}</result>
       </action>
    </package>
</struts>


Struts2的命名空间主要是为了处理同一个Web应用中包含同名Action的情形。同一个命名空间里不能有同名Action,不同的命名空间里可有同名的Action

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


              struts2命名空间的用法:

<struts>
    <constant name="struts.evMode" value=http://www.mamicode.com/"true" />>

当某个包指定了命名空间后,该包下所有的Action处理的URL应该是:命名空间/Action

Action=”命名空间/Action

http://localhost:8080/webDemo/book/getBooks.action

根命名空间:namespace=/

默认命名空间:没有指定namespace

若请求为/barsace/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只处理根命名空间下的Action请求,这是根命名空间和默认命名空间的区别

若请求为/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


(2)、Action的基本配置

              配置Action至少需要指定name(Action的名字:指定了Action所处理请求的URL);通常还需指定class(指定Action的实现类)-----该属性可选,若无则使用系统的ActionSupport

<package name="xxx">
          <action name=”login”class=”lee.LoginAction”>
             <!—配置逻辑视图和物理视图之间的映射关系-->
             <result.../>
             <result.../>
          </action>
       </package>

 Action的name屬性通常由字母和數字組成,如需在name屬性中使用(/),則需設置該常量(struts.enable.SlashesInActionNames=true)

 不推荐在Action的name属性值中使用(.)(-)

      

(3)、Action的动态方法调用(实现一个Action包含多个控制处理逻辑) 

              如同一个表单,当用户通过不同的提交按钮(登陆、注册)来提交同一个表单时,系统需用Action的不同方法来处理用户请求

      

              Struts2采用DMI(DynamicMethod Invocation动态方法调用)来处理这种请求(不推荐);

              <!— ActionName指定提交到哪个Action,methodName指定提交到指定方法 -->

              Action=”ActionName!methodName”

<input tyoe=”submit” value=http://www.mamicode.com/”登陆” />>
function regist(){
   targetForm = document.forms[0];                 // 获取页面的第一个表单
   targetForm.action = “login!regist.action”;     // 动态修改表单的action属性
}

 

 
LoginRegistAction.java:
Public class LoginRegistAction extends ActionSupport{
   private String username;
   prviate String password;
   private String tip;
   // 省略对应setter、getter方法
   // Action包含的注册控制逻辑
   public String regist() throws Exception{
      ActionContext.getContext().getSession().put(“user”,getUsername());
      setTip(“恭喜你,” + getUsername() + “,你已经注册成功!”);
      return SUCCESS;
   }
  
   // Action默认包含的控制逻辑
   public String execute() throws Exception{
      if(getUsername().equals(“lbd”) && getPassword().equals(“123”){
         ActionContext.getContext().getSession().put(“user”,getUsername());
         setTip(“欢迎,” + getUsername() + “,您已经登录成功!”);
         return SUCCESS;
      }
      else{
         return ERROR;
      }
   }
}

使用动态方法调用前需开启系统的动态方法调用:设置常量struts.enable.DynamicMethodInvocation为true

      

(4)、指定method属性 

              将一个Action处理类定义成多个逻辑Action(在配置Action时指定method属性,则可让Action调用指定方法、而不是execute方法来处理用户请求)

              <action name=”login”class=”com.LoginAction” method=”login” />

               ......

             </action>

             Action类的每个处理方法都映射成一个逻辑Action  

<package name=”lee” extends=”struts-default”>
   <!—默认使用execute方法处理请求 -->
   <action name=”login” class=”com.LoginAction”>
      <result name=”input”>/login.jsp</result>
      <result name=”error”>/error.jsp</result>
      <result name=”success”>/welcome.jsp</result>
   </action>
   <!— 指定使用regist方法处理请求 -->
   <action name=”regist” class=”com.LoginAction” method=”regist”>
      <result name=”input”>/login.jsp</result>
      <result name=”error”>/error.jsp</result>
      <result name=”success”>/welcome.jsp</result>
   </action>
</package>

修改JSP页面的JavaScript代码
function regist(){
   targetForm = document.forms[0];
   targetForm.action = “regist.action”;
}

      

         使用通配符实现动态方法调用(实现一个Action包含多个控制处理逻辑):

         <constantname="struts.enable.DynamicMethodInvocation" value=http://www.mamicode.com/"false"/>(官方推荐)

         配置<action.../>时,在name属性使用模式字符串,然后在class、method属性及<result.../>中使用{N}的形式来代表前面第N个星号(*)所匹配的字串

<package name="data-default" namespace="/" extends="struts-default">
       <default-action-ref name="login" />
       <action name="*-*-*" class="com.dhec.iems.web.action.{1}.{2}Action" method="{3}">
           <result name="dwz">common/dwzJson.jsp</result>
           <result name="input">input.jsp</result>
           <result name="error">error.jsp</result>
           <result name="index">index.jsp</result>
           <result name="download" type="stream">
              <param name="contentType">${fileType}</param>
              <param name="inputName">inputStream</param>
              <param name="contentDisposition">attachment;filename="${realFileName}"</param>
              <param name="bufferSize">8192</param>
           </result>
           <result name="preview" type="stream">
              <param name="contentType">${fileType}</param>
              <param name="inputName">inputStream</param>
              <param name="contentDisposition">inline;filename="${realFileName}"</param>
              <param name="bufferSize">8192</param>
           </result>
           <result name="success">pages/{1}/{2}-{3}.jsp</result>
           <result name="method">pages/{1}/{2}-{3}.jsp</result>
           <result name="pagedefined">${packageName}/${pageName}.jsp</result>
           <result name="pagesdefined">pages/${packageName}/${pageName}.jsp</result>
       </action>
      </package>
       

       <action name=”*_*method=”{2}” class=”actions.{1}”>

       该定义片段定义了一个模式为*_*的Action,即只要匹配该模式的请求,都可被该Action处理,如有URL为Book_save.action的请求,则调用actions.Book处理类的save方法来处理用户请求

       后面将会介绍针对Action的输入校验,在对Action进行输入校验时,必须为该Action制定对应的校验文件

       Struts2默认的校验文件命名遵守如下规则:ActionName-validation.xml

       Struts2允许制定校验文件精确到处理方法,即制定如下形式的校验文件:ActionName-methodName-validation.xml

 

       定义一个通用Action(该Action应放在最后定义)

       <action name=”*”>

          <result>/{1}.jsp</result>

       </action>

        通过这种方式,可避免让浏览者直接访问系统的JSP页面,而是让Struts2框架来管理所有用户请求


(5)、配置默认Action

             为了让Struts2的Action可以接管用户请求,可配置name=“*”的Action、除此外Struts2还支持配置默认Action; 当用户请求找不到对应的Action时,系统默认的Action即将处理用户请求

<package name=”lee”extends=”action-default”>
          <default-action-refname=”simpleViewResultAction”/>
          <!—通过action元素配置默认的Action -->
          <action name=”simpleViewResultAction”class=”com.SimpleViewResultAction”>
            <result.../>
              ......
          </action>
</package>

             将默认Action配置在默认命名空间里就可让Action处理所有请求,因为默认命名空间的Action可处理任何命名空间的请求

      

(6)、配置Action的默认处理类

              当配置<action.../>没指定class属性时,系统默认使用ActionSupport作为Action处理类

<package name=“struts-default” abstract=”true”>
     <default-class-refclass=”com.opensymphony.xwork2.ActionSupport”/>
</package>



Struts2-----6、配置Action