1. 方法调用
1. 默认方法
2. 自定义方法
3. 动态方法
一个Action类可以有多个业务逻辑方法,但是只需要配置一个Action标签,不需要method属性,在调用时指出Action名和业务逻辑方法。使用动态方法调用步骤如下:
1. struts.xml 开启动态方法调用
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
- 编写Action
- 注册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 匹配顺序
- 优先使用完全匹配
- 当完全匹配匹配上,在使用通配符匹配
- 当多个通配符都匹配上时,优先使用写在前面的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类型的区别
- dispatcher:用于页面转发,页面跳转过程一直是同一个线程,Action中的数据一直保存在。
- redirect:可用于返回一个页面、一个action、链接到一个网址。
- 缺点:redirect把一个http返回码(SUCCESS)以及返回的页面位置一起重新发给web服务器,容纳后由web服务器产生一个新的HTTP请求,就会产生一个新的线程,保存在原来Action执行的线程中的数据就无法访问。所以,result需要包含Action的数据,那么redirect不是一个可行的办法。因为新的HTTP请求时在Servlet容器的新的线程中处理的,ActionContext中的所有状态都不会存在。
- 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数据
- 采用传统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,且方法也是没有返回值
使用Struts2 方式
添加struts2-json-plugin.jar
- package 必须继承json-default
- 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. 动态结果:执行结果在配置时并不知道在运行时刻才能够确定