(1)、理解处理结果
Action处理完用户请求后,并未直接将请求转发给任何具体的视图资源,而是返回一个逻辑视图,Struts2框架收到这个逻辑视图后,把请求转发到对应的视图资源,视图资源(可为FreeMarker视图资源,甚至可将请求转给下一个Action处理,形成Action的链式处理)将处理结果呈现给用户
(2)、配置结果
Struts2的Action处理用户请求结束后,返回一个普通字符串---逻辑视图名,必须在struts.xml文件中完成逻辑视图和物理视图资源的映射,才可让系统转到实际的视图资源
简单的说,结果配置是告诉Struts2框架:当Action处理结束时,系统下一步做什么,系统下一步应该调用哪个物理视图资源来显示处理结果
根据<result…/>元素在struts.xml文件中的位置不同,配置结果分:
局部结果:将<result.../>作为<action.../>元素的子元素配置
全局结果:将<result.../>作为<global-results.../>元素的子元素配置
配置<result.../>元素可指定如下两个属性:
name:指定所配置的逻辑视图名
type:指定结果类型
<action name=”Login”class=”lee.LoginAction”>
<!—为success的逻辑视图配置Result,type属性制定结果类型 -->
<result name=”success”type=”dispatcher”>
<!—制定逻辑视图对应的实际视图资源 -->
<param name=”location”>/temp.jsp</param>
</result>
</action>
上面的<result.../>元素使用了最繁琐的形式,既制定了需映射的逻辑视图名success,也制定了结果类型dispathcer,并使用子元素的形式来制定实际视图资源;该配置表示当Action返回名为success的逻辑视图名时,系统将转发到temp.jsp页面
其中<param.../>元素中的name可取值:
location:指定该逻辑视图对应的实际视图资源
parse:指定是否允许在实际视图名字中使用OGNL表达式,默认true
通常无须指定parse参数值,故常采用如下配置实际视图资源:
<action name=”Login”class=””>
<result name=”success”type=”dispatcher”>/temp.jsp</result>
</action>
省略location参数,系统将会把<result...>…</result>中间的字符串当成实际视图资源
省略type属性,则使用系统默认的type属性(dispatcher:用于与jsp整合的结果类型):
<action name=”Login”class=””>
<result name=”success”>/temp.jsp</result>
</action>
省略name属性,则使用系统默认的name属性success:
<action name=”Login”class=””>
<result>/temp.jsp</result>
</action>
(3)、Struts2支持的结果类型
结果类型决定了Action处理结束后,下一步将 调用哪种视图资源来呈现处理结果
Struts2的结果类型要求实现com.opensymphony.xwork2.Result;该结果是所有类型的通用接口,如需自己的结果类型,应提供一个实现该接口的类,并在struts.xml文件中配置该结果类型
Struts2内建的支持结果类型:
dispatcher:直接跳转到其他URL(转发) 指定使用JSP作为视图 (默认)
redirect:直接跳转到其他URL(从定向)
chain:直接跳转到其他Action(转发) Action链式处理
redirectAction:直接跳转到其他Action(从定向)
freemarker:指定使用FreeMarker模板作为视图
velocity:指定使用Velocity模板作为视图
httpheader:控制特殊的HTTP行为
stream:向浏览器返回一个InputStream(一般用于文件下载)
xslt:与XML/XSLT整合
plainText:显示某个页面的原始代码
从action1直接跳转到action2:
1:保存前一个action的request对象:
<result name=”a2”type=”chain”>action2</result>
2:不保存前一个action的request对象:
<result name=”a2”type=”redirectAction”>action2</result>
<struts>
<constant name="struts.enable.DynamicMethodInvocation"value="false"></constant>
<package name="demo" extends="struts-default">
<action name="*Action"class="WEB.Action" method="{1}">
<result name="computerListAction"type="chain">computerListAction</result>
<result name="cartJsp">/cart.jsp</result>
<result name="cartAction"type="redirectAction">cartAction</result>
</action>
</package>
</struts>
(4)、plainText结果类型
<result type=”plainText”>
<!—制定实际的视图资源 -->
<param name=”location”>/welcome.jsp</param>
<!— 指定使用的字符集来处理页面代码 -->
<param name=”charSet”>GBK</param>
</result>
(5)、redirect结果类型
与dispatcher相对,dispatcher是将请求forward到指定的JSP资源;而redirect则将redirect到指定的视图资源
<result type=”redirect”>/welcoome.jsp</result>
(6)、redirectAction结果类型
与redirect类习惯非常相似,也是重新生成一个全新的请求;但redirectAction使用ActionMapperFactory提供的ActionMapper来重定向请求
当需要让一个Action处理结束后,直接将请求重定向到另一个Action时,应使用此结果类型
<result type=”redirectAction”>
<!—指定重定向的actionName -->
<param name=”actionName”>dashboard</param>
<!—指定重定向的Action所在的命名空间-->
<param name=”namespace”>/secure</param>
</result>
redirect:重新生成一个新请求,用于生成一个对具体资源的请求
redirectAction:重新生成一个新请求,用于生成对另一个Action的请求
(7)、动态结果
动态结果的含义是指在指定实际视图资源时用表达式语法,通过这种语法可允许Action处理完用户请求后,动态转入实际视图资源
<action name=”crud_*”class=”lee.CrudAction” method=”{1}”>
<result>/{1}.jsp</result>
</action>
(8)、Action属性值决定物理视图资源
配置<result.../>元素时,不仅可使用${0}表达式形式来指定视图资源,还可用${属性名}的方式来指定视图资源;${属性名}里的属性名就是对应Action实例里的属性;还可使用完全的OGNL表达式(${属性名.属性名.属性名})
<action name=”save” class=”org.app.action.SkillAction”method=”save”>
<!—使用OGNL表达式来制定结果资源 -->
<result type=”redirect”>edit.action?skillName=${currentSkill.name}</result>
</action>
(9)、全局结果
全局结果对所有的Action都有效
<package name=”test”extends=”struts-default”>
<!—定义全局结果 -->
<global-results>
<resultname=”success”>/${target}.jsp</result>
</global-results>
<action name=”MyAction”class=”org.app.action.MyAction” />
<action name=””>
<result>.</result>
</action>
</package>
若一个Action里包含了与全局结果同名的结果,则Action里的局部Result会覆盖全局Result
(10)、使用PreResultListener
PreResultListener是一个监听器接口,它可在Action完成控制处理之后,系统转入实际物理视图之间被回调
Struts2应用可由Action、拦截器添加PreResultListener监听器;可通过ActionInvocation的addPreResultListener()添加;一旦为Action添加了该监听器,该监听器就可在应用转入实际物理视图之前回调该监听器的beforeResult方法;一旦为拦截器添加了该监听器,该监听器会对该拦截器所拦截的所有Action都起作用
public class LoginRegistAction extendsActionSupport{
private String username;
private String password;
private String tip;
// 省略三个属性的setter、getter方法
public String regist() throwsException{
ActionContex.getContext().getSession().put(“user”,getUsername());
setTip(“恭喜你,” +getUsername() + “你已注册成功!”);
return SUCCESS;
}
public Stringexecute() throws Exception{
ActionInvocation invocation =ActionContext.getContext().getActionInvocation();
Invocation.addPreResultListener(newPreResultListener(){
public void beforeResult(ActionInvocationinvocation,String resultCode){
System.out.println(“返回的逻辑视图名字为:” + resultCode);
// 在返回Result之前加入一个额外的数据
invocation.getInvocationContext().put("extra",new java.util.Date() + "由" + resultCode + “逻辑视图名转入”);
//也可加入日志等
}
);
if(getUsername().equals("xx") && getPassword().equals("123")){
ActionContext.getContext().getSession().put("user",getUserName());
setTip("欢迎," + getUsername() + ",你已登录成功!");
return SUCCESS;
}
else{
return ERROR;
}
}
}