随笔-126  评论-247  文章-5  trackbacks-0

package 节点

<package name="user" namespace="/user" extends="struts-default" abstract="false">
  
</package>
属性名称 是否必须 属性描述
name 指定 package 的名字,这个名字在工程内必须是唯一的
extends 指明要扩展的包的名字。如 extends="struts-default"
abstract 指明 package 是否是抽象的。默认是 false。
抽象的 package 不能拥有任何的 action,只能作为父包被继承
namespace 命名空间。默认值是 ""。
若指定了该属性的值,那么,访问该 package 下的所有 Action 都需要带上这个命名空间

action 节点

<action name="domain" class="fan.tutorial.action.DomainAction" method="launch">
  <result>/domain.jsp</result>
</action>
属性名称 是否必须 属性描述
name 指定 Action 的名字
class 指定 Action 的完整类路径。
默认是 class = "com.opensymphony.xwork2.ActionSupport"
method 指定 Action 执行时调用的方法。默认是 method = "execute"

result 节点

<result name="success" type="dispatcher">/success.jsp</result>
属性名称 是否必须 属性描述
name 指定视图结果的名称,用于根据不同的逻辑名称匹配不同的视图结果页面。
默认值 name = "success"
type 指定视图结果类型,用于根据不同的类型 ( 例如转发或重定向等 ) 跳转到指定的视图页面
默认值 type = "dispatcher"

result 节点的结果类型

结果类型名称 结果类型描述
chain 用于将多个 Action 链接起来执行,来共同完成一次请求 ( 数据可以在多个 Action 中共享 )
dispatcher 转发。这是默认的结果类型。
本质是通过 Servlet API 的 RequestDispatcher.forward() 来完成
redirect 重定向。
本质是通过 Servlet API 的 HttpServletResponse.sendRedirect() 来完成。
重定向是服务器向客户端浏览器发回302状态码以及重定向地址 Location,浏览器接收后将重新发起一次新的 HTTP 请求。前一次 HTTP 请求所包含的数据是不能被后一次 HTTP 请求所共享的。
redirectAction 与 redirect 结果类型相似,只是它专门用来映射到另外的一个 Action 动作
stream 向客户端浏览器发送 InputStream 流对象,通常可以用来作为文件下载的一种手段

配置全局结果

<package name="basic" extends="struts-default">
  <global-results>
    <result name="error">/pages/global/error.jsp</result>
    <result name="success">/pages/global/success.jsp</result>
  </global-results>
</package>
全局结果是在 package 中定义的,全局结果定义完成后,该 package 下的所有 action 都能来使用它们。
其余 package 如果也想来使用这些结果,那么需要通过 extends 来继承该 package 才能使用。

配置默认 action

<package name="default" extends="struts-default">
  <default-action-ref name="invalidAction" />
  <action name="invalidAction">
    <result type="redirect">/index.jsp</result>
  </action>
</package>
在没有配置默认 action 之前,若访问一个不存在的 action,那么服务器端将报出错误,客户端浏览器得到的是 HTTP ERROR: 404 的错误提示页面。
在配置好默认的 action 之后,若访问一个不存在的 action,那么这个默认的 action 将被执行并将执行完成的结果视图发回给客户端。
另外,<default-action-ref> 节点需要在 <action> 节点之前声明,否则在启动时将报出错误。

package 的运用

<struts>
  
  <package name="first" namespace="/first" extends="struts-default">
    <action name="access">
      <result>/pages/package/first.jsp</result>
    </action>
  </package>
  
  <package name="second" extends="struts-default">
    <action name="access">
      <result>/pages/package/second.jsp</result>
    </action>
  </package>
  
  <package name="third" extends="struts-default" abstract="true">
    <global-results>
      <result>/pages/package/third.jsp</result>
    </global-results>
  </package>

  <package name="fourth" namespace="/fourth" extends="third">
    <action name="access" />
  </package>
  
</struts>
这里总共配置了4个 package,其中一个是抽象的,其余3个 package 中分别定义了一个 action,action 节点的 class 和 method 属性不指定 ( 使用默认 ),并且 action 的 name 属性都指定为 access ( 极端示例,切勿效仿 ☺ )。
访问 first package 下的 action 的方式为:/first/access.action
访问 second package 下的 action 的方式为:/access.action 或 /xxx/access.action 或 /xxx/yyy/access.action ( xxx、yyy 代表任意串 )
访问 fourth package 下的 action 的方式为:/fourth/access.action
不知道你注意了没有,这里的 second package 的命名空间是没有指定的,也就是说它能捕获所有的命名空间串。那好,现在问题来了,当访问 /first/access.action 的时候,得到的视图为什么是 first.jsp 而不是 second.jsp 呢?这是不是跟 package 节点在配置文件中出现的先后顺序有关系呢?( 有过 WEB 开发的都知道,配置文件中节点的先后顺序有时候是很重要的 )。这个很明显,当访问 /fourth/access.action 的时候,得到的是 third.jsp 而不是 second.jsp。事实上,Struts2 是首先根据 URL 中的命名空间去相对应的 package 下查找 action,如果查找不到,才到默认的命名空间的 package 中去查找 action,如果有多个 package 都使用了默认的命名空间,这个时候才是根据 package 出现的先后顺序来查找 action 的。

action 的运用

package fan.tutorial.action;

import com.opensymphony.xwork2.Action;

public class ExampleAction implements Action {

    public String execute() {
        System.out.println("--- ExampleAction[execute] ---");
        return SUCCESS;
    }

    public String launch() {
        System.out.println("--- ExampleAction[launch] ---");
        return "launch";
    }

    public String load() {
        System.out.println("--- ExampleAction[load] ---");
        return "load";
    }

}
<struts>
  
  <package name="simple" namespace="/simple" extends="struts-default">
    <action name="example" class="fan.tutorial.action.ExampleAction">
      <result name="load">/pages/example/load.jsp</result>
      <result name="launch">/pages/example/launch.jsp</result>
      <result name="success">/pages/example/success.jsp</result>
    </action>
    <action name="example2" class="fan.tutorial.action.ExampleAction" method="load">
      <result name="load">/pages/example/load.jsp</result>
      <result name="launch">/pages/example/launch.jsp</result>
      <result name="success">/pages/example/success.jsp</result>
    </action>
  </package>
  
</struts>
这里配置了2个 action,不同的是,第2个 action 使用了 method 属性,那么当访问 /simple/example2.action 的时候,由 method 指定的方法将被执行。
而第1个 action 没有指定 method 属性,那么当访问 /simple/example.action 的时候,默认执行的是 execute 方法。

action 动态方法的调用

Struts2 Action 动态方法调用非常简单,就是在 action 名称后面使用 "!" 来链接需要执行的方法的名称就可以了。以上面的配置为例,如想调用 ExampleAction 的 launch 方法,只需要访问 /simple/example!launch.action 就可以了。

使用通配符映射 action

<struts>
  
  <package name="wildcard" namespace="/wildcard" extends="struts-default">
    <action name="*_*" class="fan.tutorial.action.{1}Action" method="{2}">
      <result name="{2}">/pages/example/{2}.jsp</result>
    </action>
  </package>
  
</struts>
通配符 "*" 匹配的值用符号 {n} 来访问得到。第1个 "*" 用 {1} 来访问,其余的以此类推。
使用通配符后,如果想执行 ExampleAction 的 launch 方法,访问 /wildcat/Example_launch.action 即可。
需要注意的是,这里的 Example 必须是要大写字母开头的,因为它是用来定位我们的 Action 类路径的,它必须与你的类名称保持高度一致。

dispatcher 结果类型的运用

package fan.tutorial.action;

import com.opensymphony.xwork2.Action;

public class LoginAction implements Action {

    private String username;
    private String password;
    
    public String execute() {
        System.out.println("**************************");
        System.out.println("LoginAction: ");
        System.out.println("username = " + username + ", password = " + password);
        System.out.println("**************************");
        return SUCCESS;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}
package fan.tutorial.action;

import com.opensymphony.xwork2.Action;

public class ManagerAction implements Action {

    private String username;
    private String password;
    
    public String execute() {
        System.out.println("**************************");
        System.out.println("ManagerAction: ");
        System.out.println("username = " + username + ", password = " + password);
        System.out.println("**************************");
        return SUCCESS;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}
<struts>
  
  <package name="result" namespace="/result" extends="struts-default">
    <action name="login" class="fan.tutorial.action.LoginAction">
      <result type="dispatcher">/pages/result/login.jsp</result>
    </action>
    <action name="manager" class="fan.tutorial.action.ManagerAction">
      <result type="dispatcher">/pages/result/manager.jsp</result>
    </action>
  </package>
  
</struts>
<html>
  <h1>${username}, ${password}</h1>
</html>
dispatcher 是默认的结果类型,也是最常用的结果类型。
当访问 /result/login.action?username=u&password=p 的时候,在 login.jsp 中输出相应的信息,这个比较简单,就不多说了。

chain 结果类型的运用

<struts>
  
  <package name="result" namespace="/result" extends="struts-default">
    <action name="login" class="fan.tutorial.action.LoginAction">
      <result type="chain">manager</result>
    </action>
    <action name="manager" class="fan.tutorial.action.ManagerAction">
      <result type="dispatcher">/pages/result/manager.jsp</result>
    </action>
  </package>
  
</struts>
访问 /result/login.action?username=u&password=p,在控制台可以看到,LoginAction 和 ManagerAction 的 execute 方法依次被执行并打印出相应的信息,请求中携带的数据在两个 Action 中被共享,最终在 manager.jsp 中显示相应的信息。
需要注意的是,在 chain 中不能为 action 指定扩展名,如 manager.action 等是不正确的。

redirect 结果类型的运用

<struts>
  
  <package name="result" namespace="/result" extends="struts-default">
    <action name="login" class="fan.tutorial.action.LoginAction">
      <result type="redirect">/pages/result/login.jsp</result>
    </action>
    <action name="manager" class="fan.tutorial.action.ManagerAction">
      <result type="redirect">
        /pages/result/manager.jsp?username=${username}&amp;password=${password}
      </result>
    </action>
  </package>
  
</struts>
当访问 /result/login.action?username=u&password=p 的时候,控制台打印出了接收到的参数的信息,但是 login.jsp 页面中不会显示参数信息,这是由于重定向引起的,上面已经有提及到,这里就不再赘述。
若想使用 redirect 又不想丢失一些你感兴趣的数据,那么,可以采用像第2个 action 的配置方式,在重定向的时候,重新把一些必要的信息传回去就可以了。
需要注意的是,若有多个参数,不能像平常那样使用 "&" 来连接,而是需要使用它的实体名称 ( &amp; ) 来连接。否则,工程在启动的时候是会报出错误的。

redirectAction 结果类型的运用

<struts>
  
  <package name="result" namespace="/result" extends="struts-default">
    <action name="login" class="fan.tutorial.action.LoginAction">
      <result type="redirectAction">manager</result>
    </action>
    <action name="login_alias" class="fan.tutorial.action.LoginAction">
      <result type="redirectAction">
        manager?username=${username}&amp;password=${password}
      </result>
    </action>
    <action name="manager" class="fan.tutorial.action.ManagerAction">
      <result type="dispatcher">/pages/result/manager.jsp</result>
    </action>
  </package>
  
</struts>
当访问 /result/login.action?username=u&password=p 的时候,在控制台,LoginAction 的 execute 方法执行并将接收得到的参数信息打印了出来,
而 ManagerAction 的 execute 方法执行打印出来的参数信息是 null,说明执行到 ManagerAction 的时候,之前的 HTTP 请求参数已经丢失了,同样的,这是由于重定向造成的。
如果不想丢失数据,可以参考 login_alias 的配置方式。需要注意的问题和上面 redirect 提到的是一样的。实际上,这里的 redirectAction 也可以换成 redirect 的,它们达到的效果是一样的。

stream 结果类型的运用

考虑到文章篇幅过长,这个将留到下一篇文章中来专门介绍。这里暂且略过。

配置动态结果

package fan.tutorial.action;

import java.util.Random;
import com.opensymphony.xwork2.Action;

public class DynamicResultAction implements Action {

    private String resultView;
    
    public String execute() {
        if(new Random().nextInt(100) % 2 == 0){
            resultView = "even";
        }else{
            resultView = "odd";
        }
        return SUCCESS;
    }

    public String getResultView() {
        return resultView;
    }

}
<struts>
  
  <package name="result" namespace="/result" extends="struts-default">
    <action name="dynamic" class="fan.tutorial.action.DynamicResultAction">
      <result>/pages/result/${resultView}.jsp</result>
    </action>
  </package>
  
</struts>
这里使用了 ${resultView} 表达式,这要求 Action 类中必须有一个 public String getResultView() 方法。

文章示例源码下载

struts-xml.zip


  
posted on 2014-03-12 19:58 fancydeepin 阅读(1961) 评论(2)  编辑  收藏

评论:
# re: Struts2 配置文件 struts.xml 2014-03-13 09:57 | 魏五锁业
支持博主分享  回复  更多评论
  
# re: Struts2 配置文件 struts.xml 2014-03-13 11:00 | 万利锁业
支持博主更新   回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: