(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; } } }