1. Struts2的结果视图
Struts2的每一个atcion都可以有不同的结果返回方式,在result中返回结果类型type属性有11种返回结果类型的方式。最主要最常用的有redirect、redirectAction、dispather三种跳转方式。
具体跳转方式的type类型可以在struts-default.xml中查找到,具体如下:
<package name="struts-default" abstract="true"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" /> </result-types>
1.1.redirectAction配置
redirectAtion跳转类型主要是用于跳转至另外一个Action的结果视图中。
主要情况有两种:
① 访问本包目录下的另外一个Action的结果视图,配置示例如下:
<!--测试redirectAction跳转类型:访问本包目录下的action 在结果视图中直接填写本包中的另外一个action的name值,即可完成另外一个 action结果视图中的跳转方式--> <action name="index" class="cn.yif.action.UserAction" method="execute"> <result name="success" type="redirectAction"> testSave </result> </action> <action name="testSave" class="cn.yif.action.UserAction" method="testSave"> <result name="Success" type="dispatcher"> /success.jsp </result> </action>
② 访问另外一个包(不同包)中的Action结果视图,具体配置示例如下:
这里有两种方式:
第一种是依旧使用redirect跳转方式,在结果视图中配置另外一个包的跳转映射路径:namespace/actionName
<package name="default" namespace="/" extends="struts-default"> <!--测试在当前包访问另外一个包中action的结果视图--> <action name="index" class="cn.yif.action.UserAction" method="execute"> <result name="success" type="redirect"> /system/testSave </result> </action> </package> <package name="system" namespace="/system" extends="struts-default"> <action name="testSave" class="cn.yif.action.UserAction" method="testSave"> <result name="Success" type="dispatcher"> /success.jsp </result> </action> </package>
第二种使用redirectAction,需要在result标签中配置param参数,具体配置如下:
<package name="default" namespace="/" extends="struts-default"> <!--测试redirectAction跳转类型:访问本包目录下的action 在结果视图中直接填写本包中的另外一个action的name值,即可完成另外一个 action结果视图中的跳转方式--> <!--使用redirectAction,在result标签中添加param参数namespace与actionName, 分别对应另一个package中的namespace与action的name的值--> <action name="index" class="cn.yif.action.UserAction" method="execute"> <result name="success" type="redirectAction"> <param name="namespace">system</param> <param name="actionName">testSave</param> </result> </action> </package> <package name="system" namespace="/system" extends="struts-default"> <action name="testSave" class="cn.yif.action.UserAction" method="testSave"> <result name="Success" type="dispatcher"> /success.jsp </result> </action> </package>
1.2.自定义resultType类型
在struts-default.xml中可以找到对应的result-types,在<package>中可以配置自定义的result-types来创建新的返回类型(这种返回类型完全是根据自己来命名的)。具体配置如下:
<package name="default" namespace="/" extends="struts-default"> <!--配置result-types:使用struts-default.xml中的返回类型默认default配置 这里主要是可以自定义type的名称,比如我自己定义一个跳转类型为forward--> <result-types> <result-type name="forward" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> </result-types> <action name="index" class="cn.yif.action.UserAction" method="execute"> <result name="success" type="forward"> /WEB-INF/view/test.jsp </result> </action> </package>
1.3.局部结果视图和全局结果视图
局部结果视图:
配置在一个<action>标签中的<result>结果视图叫做局部结果视图,这个结果视图只能在当前这个Action中使用。
当Action处理完用户请求时,会返回一个字符串,这个普通的字符串就是一个逻辑视图的名称。
<package name="default" namespace="/" extends="struts-default"> <action name="index" class="cn.yif.action.UserAction" method="execute"> <!--局部结果视图:在一个Action标签中配置,将<result>作为<action>子元素配置;只有这个Action可以使用--> <result name="success" type="dispatcher"> /success.jsp </result> <!--success与error都是逻辑视图名称,决定响应哪个结果--> <result name="error" type="dispatcher"> /error.jsp </result> </action> </package>
全局结果视图:
在一个package中配置<global-results>,在其中定义<result>结果视图名称,这个结果视图就是一个全局的结果视图。配置之后可以供该package下所有action结果视图进行访问。
<!--全局结果视图:配置之后可以在多个action中进行访问--> <global-results> <result name="testExample"> /WEB-INF/view/test.jsp </result> </global-results>
注意:如果在某一个<action>下有一个和全局视图名称一样的result,那么访问时会以局部结果视图为准。
<!--全局结果视图:配置之后可以在多个action中进行访问--> <global-results> <result name="testExample"> /WEB-INF/view/test.jsp </result> </global-results> <action name="example" class="cn.yif.action.ExampleAction" method="test"> <!--我和全局的结果视图名称相同,但是以我的为准--> <result name="testExample" type="dispatcher"> /WEB-INF/view/test.jsp </result> </action>
2. 创建Action类的三种方式
方式一 创建一个简单的POJO类:
/** * 就是一个简单的pojo类而已 * 必须提供一个公共的无参的构造方法 -- 反射需要调用 * */ public class CreateActionOne { public CreateActionOne() { } public String execute(){ return "success"; } }
方式二 实现Action接口(注意是xwork2包中的Action接口):
import com.opensymphony.xwork2.Action; public class CreateActionTwo implements Action { @Override public String execute() throws Exception { return SUCCESS; } }
方式三 继承ActionSupport
import com.opensymphony.xwork2.ActionSupport; /** * 继承ActionSupport */ public class CreateActionThree extends ActionSupport { @Override public String execute() throws Exception { return super.execute(); } }
3. 通配符*映射路径配置
① 通过*配置对应Action中的结果视图方法,管理多个结果视图映射地址;
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <!--使用通配符*定义action中的name属性,注意索引是从1开始,这样命名可以管理多个结果视图--> <package name="default" namespace="/" extends="struts-default"> <action name="crud_*" class="cn.yif.action.CrudAction" method="{1}"> <result name="{1}" type="dispatcher"> /WEB-INF/view/{1}.jsp </result> </action> </package> </struts>
4. Struts2接收参数的三种方式
4.1.接收普通界面参数
Struts2接收前台界面上的多个普通参数,对应的Action与struts.xml中配置如下:
ParamAction.java
/** * 1.首先需要提供对应的成员变量,成员变量的名称必须和form表单中的name值一致 * 2.需要在Action中提供对应成员变量的setter方法 */ public class ParamAction extends ActionSupport { private String name; private String password; private Integer age; @Override public String execute() throws Exception { System.out.println(name); System.out.println(password); System.out.println(age); return "success"; } public void setName(String name) { this.name = name; } public void setPassword(String password) { this.password = password; } public void setAge(Integer age) { this.age = age; } }
Struts.xml配置:
<!--action中的name对应form表单中的action--> <package name="default" namespace="/" extends="struts-default"> <action name="params" class="cn.yif.action.ParamAction" method="execute"> <result name="success" type="dispatcher"> /success.jsp </result> </action> </package>
login.jsp中form表单:
<body> <form action="/params" method="post"> 姓名:<input type="text" name="name"/><br/> 密码:<input type="password" name="password"/><br/> 年纪:<input type="number" name="age"/> <input type="submit" value="提交"/> </form> </body>
4.2.接收Object对象参数
对于界面有多个参数值需要传递的情况,可以把参数封装成对象进行传递。
/** * 提供User对象属性,并提供getUser方法 */ public class ParamUserAction extends ActionSupport { private User user; @Override public String execute() throws Exception { System.out.println(user); System.out.println(user.getDept().getName()); return "success"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
User与Dept:
public class User { private String name; private String password; private Integer age; private Date bornDate; private Boolean sex; private Dept dept; //getter/setter与toString()略 } public class Dept { private String name; }
Form表单界面:
<form action="params2" method="post"> 用户名:<input type="text" name="user.name"/><br/> 密码:<input type="password" name="user.password"/><br/> 年纪:<input type="number" name="user.age"/><br/> 日期:<input type="date" name="user.bornDate"/><br/> 性别:<input type="radio" name="user.sex" value="true">男 <input type="radio" name="user.sex" value="false">女<br/> 部门:<select name="user.dept.name"> <option value="开发部">开发部</option> <option value="人事部">人事部</option> <option value="运营部">运营部</option> </select> <input type="submit" value="提交"/> </form>
4.3.实现ModelDriven接口
/** * 当界面参数类型即有对象又有单独的普通输入类型,可以选择实现ModelDriven<T> */ public class ParamModelDrivenAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); private String email; @Override public String execute() throws Exception { System.out.println(user); System.out.println(email); return "success"; } @Override public User getModel() { return user; } public void setEmail(String email) { this.email = email; } }
Form表单:
<form action="params3" method="post"> 用户名:<input type="text" name="user.name"/><br/> 密码:<input type="password" name="user.password"/><br/> 年纪:<input type="number" name="user.age"/><br/> 日期:<input type="date" name="user.bornDate"/><br/> 性别:<input type="radio" name="user.sex" value="true">男 <input type="radio" name="user.sex" value="false">女<br/> 部门:<select name="user.dept.name"> <option value="开发部">开发部</option> <option value="人事部">人事部</option> <option value="运营部">运营部</option> </select><br/> 邮箱:<input type="text" name="email"><br/> <input type="submit" value="提交"/> </form>