且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

07 Struts2 方法调用及返回值

更新时间:2022-08-22 10:20:54

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hxdeng/article/details/81736347

1. 方法调用

1. 默认方法

2. 自定义方法

3. 动态方法

一个Action类可以有多个业务逻辑方法,但是只需要配置一个Action标签,不需要method属性,在调用时指出Action名和业务逻辑方法。使用动态方法调用步骤如下:
1. struts.xml 开启动态方法调用

<constant name="struts.enable.DynamicMethodInvocation" value="true" />
  1. 编写Action
  2. 注册Action
<!-- 2.5 版本后需要配置此属性才能够使用动态方法和通配符 -->
<global-allowed-methods>regex:.*</global-allowed-methods>
<action name="userinfoAction" class="com.javaee.struts2.action.UserinfoAction">
    <result>/index.jsp</result>
</action>

==注意== 2.5 版本后为了安全动态方法和通配符在使用的时候需要添加如下代码:

<global-allowed-methods>regex:.*</global-allowed-methods>

禁用动态方法

<constant name="struts.enable.DynamicMethodInvocation" value="false"/>

动态方法特点:
1. 一个Action类中有多个业务方法
2. 一个Action类只需要配置一个标签
3. 相比使用method属性,Action的配置数量减少
4. 请求时指明Action和业务方法

==总结==:动态方法核心就是去掉Action中method属性,在URL请求调用的时候通过!携带方法名称

4. 通配符

<action name="user_*" class="com.javaee.struts2.action.UserinfoAction" method="{1}">
    <result name="success">/index.jsp</result>
</action>
<action name="*_*" class="com.javaee.struts2.action.{1}Action" method="{2}">
    <result name="success">/index.jsp</result>
</action>

Action 匹配顺序

  1. 优先使用完全匹配
  2. 当完全匹配匹配上,在使用通配符匹配
  3. 当多个通配符都匹配上时,优先使用写在前面的action

默认Action配置

当访问Action 找不到的时候会访问默认Action

<default-action-ref name="index" />

<action name="index">
    <result>/index.jsp</result>
</action>

2. 返回值

2.1 name 属性

==result== : 每个Action 返回一个字符串,Struts2根据这个值来决定响应什么结果。
==name属性==:result的逻辑名称。和Action里返回值匹配。默认是success
==值==:指定对应的实际资源位置

2.2 type 属性

type 属性指定result的类型,不同类型的result 代表的不同的结果输出
type默认是是转发(dispatcher)

type 常见取值介绍

type 属性取值 值说明
==chain== 用来处理Action链,被跳转的Action种任能够 获取上个页面的值。如:request信息
==dispatcher== 页面转发,默认结果类型
==redirect== 请求重定向指定的URL或者Action
==redirectAction== 请求重定向到指定的Action
==json== 实现Ajax时返回JSON对象
freemarker 整合freemarker模板结果类型
httpheader 处理特殊Http行为结果
stream 向浏览器发送InputStream对象,通常用来处理文件下载,还可以用于Ajax数据
xslt 用来整合XML/XSLT结果类型
velocity 用来整合Velocity 模板结果类型
plainText 显示原始文件内容。例如文件源代码
postback 使当前请求参数以表单形式提交

2.3 struts2 中 dispatcher、redirect和chain类型的区别

  1. dispatcher:用于页面转发,页面跳转过程一直是同一个线程,Action中的数据一直保存在。
  2. redirect:可用于返回一个页面、一个action、链接到一个网址。
  3. 缺点:redirect把一个http返回码(SUCCESS)以及返回的页面位置一起重新发给web服务器,容纳后由web服务器产生一个新的HTTP请求,就会产生一个新的线程,保存在原来Action执行的线程中的数据就无法访问。所以,result需要包含Action的数据,那么redirect不是一个可行的办法。因为新的HTTP请求时在Servlet容器的新的线程中处理的,ActionContext中的所有状态都不会存在。
  4. chain:功能与redirect的action转发类似,不过与redirectaction转发功能不同的是它可以将Action中的数据一直保存在同一个HTTP请求中。

==1.跳转方式==
dispatcher和chain是服务器端跳转,所以客户端只发起一次请求,产生一个action;
redirect和redirectAction是客户端跳转,所以客户端发起两次请求。

==2.跳转内==容
dispatcher和redirect跳转的是views(一般是jsp页面);
chain和redirectAction跳转的是一个action。

2.3 全局返回结果

<!-- 全局返回配置,必须放在action的前面 -->
<!-- action中的result优先于全局result,当全局的result和Action中的result中都没有配置的时候就去父类中查找,如果父类中没有时就回报错 -->
<global-results>
    <result name="error">/error.jsp</result>
</global-results>

==全局结果总结==
1. 使用 来配置,只不过不是在中配置,而是在中嵌套
2. 当所有Action需要共享某个结果时,可以定义为全局结果、
3. 全局结果的影响范围整个包含的所有Action,如果不是对所有Action都有效的结果,不要定义在全局返回结果中

==Result搜索顺序==
1. 首先找自己的元素内的元素是否有匹配的。如果有就执行这个result,没有执行下一步
2. 其次找自己所在的包的全局result是否有匹配的,如果有就执行这个result,没有执行下一步
3. 递归寻找自己的包的父包、祖包中的全局result是否有匹配的,如果有就执行这个result,没有执行下一步
4. 最后都没找到就抛出Exception异常

2.4 动态返回结果

private HouseUser user;
//记录下一个跳转的Action是谁
private String nextDispose;
//userACtion访问的方法
public String login() {
    if (user.getUsername().equals("common")&& user.getPassword().equals("common")) {
        nextDispose = "common";// 下一个result中name的别名
        return SUCCESS;
    } else if (user.getUsername().equals("admin")&& user.getPassword().equals("admin")) {
        nextDispose = "admin";
        return SUCCESS;
    } else {
        return INPUT;
    }
}
//省略getXXX()/setXXX()
<!-- 动态结果 -->
<package name="user" namespace="/user" extends="struts-default">
    <action name="login" class="com.javaee.struts2.action.UserAction" method="login">
        <result name="success" type="redirectActioin">${nextDispose}</result>
        <result name="input">/login.jsp</result>
    </action>
</package>

2. 返回JSON数据

  1. 采用传统JSON输出
    方法没有返回值,通过Struts2调用Servlet 底层API获得Response对象(HttpServletResponse response=ServletActionContext.getResponse();
    )进行JSON数据输出

struts.xml配置

<package name="default" extends="struts-default" namespace="/">
    <action name="testJsonAction" class="com.javaee.struts2.action.TestJsonAction"  method="doAction">
    </action>
</package>

==注意==:action 没有result,且方法也是没有返回值

  1. 使用Struts2 方式

  2. 添加struts2-json-plugin.jar

  3. package 必须继承json-default
  4. result 返回值 type类型修改为json
<result type="json">
    <!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
    <!-- 默认将会序列所有有返回值的getter方法的值,而无论该方法是否有对应属性 -->
    <param name="root">dataMap</param>

    <!-- 指定是否序列化空的属性 -->
    <param name="excludeNullProperties">true</param>

    <!-- 这里指定将序列化dataMap中的那些属性 -->
    <param name="includeProperties">userList.*</param>

    <!-- 取消浏览器缓存-->
  <param name="noCache">true</param>
  
  <!-- 设置服务器响应类型-->
  <param name="contentType">application/json</param>
  
    <!-- 这里指定将要从dataMap中排除那些属性,这些排除的属性将不被序列化,一半不与上边的参数配置同时出现 -->
    <param name="excludeProperties">SUCCESS</param>
</result>

==result==总结
1. name 属性:result逻辑名称,和Action里返回值匹配,默认”success”
2. type 属性:结果类型,默认dispatcher
3. 全局结果:通过 配置,对包内所有Action都有效的结果
4. 动态结果:执行结果在配置时并不知道在运行时刻才能够确定