问题:在struts2框架下,如何将表单数据传递给业务控制器Action。
struts2中,表单想Action传递参数的方式有两种,并且这两种传参方式都是struts2默认实现的,他们分别是基本属性注入、域模型注入
、其中:
---基本属性注入,是将表单的数据项分别传入给Action中的一些基本基本类型。
---域模型注入,是将表单的数据项打包传入给Action中的一个实体对象。
我们项目Struts2的实例,在其基础上使用这2中方式完成页面向Action的参数传递。具体的我们可以在项目首页regist.jsp上追加表单,
并在表单中模拟一些数据,将这些数据提交给RegistAction,最后在RegistAction中将接受的参数输出到控制台。
具体实现步骤:
1>基本属性注入
步骤一:
在项目的regist.jsp中,追加表单,并将该表单设置提交给RegistAction,即将form的action属性设置为:
<form action="regist" method="post">
在表单中增加一个文本框,用于输入一个公司姓名,该文本框的name属性值为company。代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%> <%@ page contentType="text/html;charset=gbk"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>京东商城注册页面</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <% request.setCharacterEncoding("gbk"); %> </head> <body> <center> <form action="regist" method="post"> 公 司: <input type="text" name="company"/> <br> <table> <tr> <td><input type="submit" value="注册"/></td> <td><input type="reset" value="重置" ></td> </tr> </table> </form> <s:fielderror /> </center> </body> </html>
步骤二:RegistAction中,接收表单传入的参数
在RegistAction中,追加属性并用于接收表单传入的姓名参数,该属性的名称要求与文本框的值相同(company),并且该属性需要
具备set方法。在业务方法中输出属性company的值。通知为了方便观察代码执行的顺序,在Action默认构造器中,输出任意的文字,
代码如下:
package com.wss.action; import com.opensymphony.xwork2.ActionSupport; import com.wss.Dao.School; import com.wss.Dao.User; import com.wss.Dao.UserDao; public class RegistAction extends ActionSupport{ public RegistAction() { System.out.println("Initialization RegistAction...."); } private String company; public void setCompany(String company) { System.out.println("Setting the company"); this.company=company; } public String execute() throws Exception{ UserDao ud =new UserDao(); System.out.println("The company is "+this.company); //if(ud.regist(user)!=0){ this.addFieldError("success", "注册成功"); return SUCCESS; //} //this.addFieldError("error", "注册失败"); //return ERROR; } }
步骤三:测试
重新部署该项目并启动tomcat,打开浏览器,针对当前的案例,在地址栏中输入地址:
http://localhost:8080/ShopDemo/regist.jsp
运行结果:
点击提交:
Eclipse控制台输出:
Initialization RegistAction....
Setting the company
The company is 公司
控制台输出的顺序可以证明代码的执行顺序:实例化Action--->调用set方法注入参数company的值-->调用业务方法execute(),
当然这个过程是Struts2的API自行实现的,我们只需要在写代码时满足上述步骤中的要求即可。
2>域模型注入一(Action中属性用private User user =new User();已创建)
步骤一:修改表单,追加演示数据
在regist.jsp修改表单,追加用户名、密码、电话和地址四个文本框,模拟输入用户的相关信息,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%> <%@ page contentType="text/html;charset=gbk"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>京东商城注册页面</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <% request.setCharacterEncoding("gbk"); %> </head> <body> <center> <form action="regist" method="post"> 用户名:<input type="text" name="user.name"/><br> 密 码:<input type="password" name="user.password"/><br> 手 机:<input type="text" name="user.phone" /><br> 地 址:<input type="text" name="user.address"/><br> 公 司: <input type="text" name="company"/> <br> <table> <tr> <td><input type="submit" value="注册"/></td> <td><input type="reset" value="重置" ></td> </tr> </table> </form> <s:fielderror /> </center> </body> </html>
步骤二:创建实体类
创建包com.wss.Dao,用于存放实体类。在com.wss.Dao包下创建实体类User,用于封装表单中追加的数据,即用户名、密码、
电话和地址。User中要包含两个属性,用于封装用户名、密码电话和地址,并给属性提供get和set方法,代码如下:
package com.wss.Dao; public class User { private int id; private String name; private String password; private String phone; private String address; public User() { System.out.println("Initialization the User......"); } public int getId() { System.out.println("Getting the ID"); return id; } public void setId(int id) { System.out.println("Setting the ID"); this.id = id; } public String getName() { System.out.println("Getting the name"); return name; } public void setName(String name) { System.out.println("Setting the name"); this.name = name; } public String getPassword() { System.out.println("Getting the password"); return password; } public void setPassword(String password) { System.out.println("Setting the password"); this.password = password; } public String getPhone() { System.out.println("Getting the phone"); return phone; } public void setPhone(String phone) { System.out.println("Setting the phone"); this.phone = phone; } public String getAddress() { System.out.println("Getting the address"); return address; } public void setAddress(String address) { System.out.println("Setting the address"); this.address = address; } }
步骤三:修改RegistAction,接受表单传入的参数
在RegistAction中,追加属性用于接受表单传入的用户名、密码、电话和地址参数,该属性的类型为User类型,名称为user,并为
该属性提供get和set方法。
在业务方法(execute())中输出属性user的值,代码如下:
package com.wss.action; import com.opensymphony.xwork2.ActionSupport; import com.wss.Dao.School; import com.wss.Dao.User; import com.wss.Dao.UserDao; public class RegistAction extends ActionSupport{ public RegistAction() { System.out.println("Initialization RegistAction...."); } private User user =new User(); //private User user; public User getUser() { System.out.println("Getting the getUser"); return user; } public void setUser(User user) { System.out.println("Setting the setUser"); this.user = user; }private String company; public void setCompany(String company) { System.out.println("Setting the company"); this.company=company; } public String execute() throws Exception{ UserDao ud =new UserDao(); System.out.println("The company is "+this.company+" The name is "+this.user.getName()+" The phone is "+this.user.getAddress()); //if(ud.regist(user)!=0){ this.addFieldError("success", "注册成功"); return SUCCESS; //} //this.addFieldError("error", "注册失败"); //return ERROR; } }
步骤四:修改表单,设置文本框属性
在regist.jsp中,修改表单新增的4个文本框name属性值。对于域模型注入的方式,文本框name属性值应该是具有"对象名.属性名"
格式的表达式。
其中对象名指的是Action中的实体类型属性名,即User对象实例,属性名指的是实体类型中的属性名
(name,password,phone,address),代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%> <%@ page contentType="text/html;charset=gbk"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>京东商城注册页面</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <% request.setCharacterEncoding("gbk"); %> </head> <body> <center> <form action="regist" method="post"> 用户名:<input type="text" name="user.name"/><br> 密 码:<input type="password" name="user.password"/><br> 手 机:<input type="text" name="user.phone" /><br> 地 址:<input type="text" name="user.address"/><br> 公 司: <input type="text" name="company"/> <br> <table> <tr> <td><input type="submit" value="注册"/></td> <td><input type="reset" value="重置" ></td> </tr> </table> </form> <s:fielderror /> </center> </body> </html>
步骤五:测试
重新部署项目并启动tomcat,在浏览器中输入地址:http://localhost:8080/ShopDemo/regist.jsp
效果如下图所示(当然为了稍候测试方便,我自己输入了一些信息):
点击提交,查看myeclipse的控制台,输出结果如下:
Initialization the User...... Initialization RegistAction.... Setting the company Getting the getUser Setting the name Getting the getUser Setting the password Getting the getUser Setting the phone Getting the name Getting the address The company is 公司 The name is good The phone is 111
控制台输出的顺序可以证明代码的执行顺序为:实例化Action-->实例化User并注入参数-->调用set方法注入User对象-->调用业务
方法。
但这个时候是先实例化User对象,再实例化Action对象,主要是因为Action中有private User user =new User();创建实例对象前,一般会对静态属性、静态对码段,对象属性按顺序进行初始化后,才调用Action的构造函数;user实例化后(我自己感觉实例化后并
把user对象注入了,即相当于调用了setUser方法);
再接着
Getting the getUser
Setting the name
Getting the getUser
Setting the password
Getting the getUser
Setting the phone
Getting the name
Getting the address
用于调用set方法注入user对象各属性。
3>域模型注入二(Action中属性 private School school;没有用new创建对象)
步骤一:修改表单,追加演示数据
在regist.jsp修改表单,追加用学校、城市、院系三个文本框,模拟输入用户的相关信息,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%> <%@ page contentType="text/html;charset=gbk"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>京东商城注册页面</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <% request.setCharacterEncoding("gbk"); %> </head> <body> <center> <form action="regist" method="post"> 用户名:<input type="text" name="user.name"/><br> 密 码:<input type="password" name="user.password"/><br> 手 机:<input type="text" name="user.phone" /><br> 地 址:<input type="text" name="user.address"/><br> 公 司: <input type="text" name="company"/> <br> 学 校:<input type="text" name="school.name"/> 城 市:<input type="text" name="school.city" /> 院 系:<input type="text" name="school.department" /> <table> <tr> <td><input type="submit" value="注册"/></td> <td><input type="reset" value="重置" ></td> </tr> </table> </form> <s:fielderror /> </center> </body> </html>
步骤二:创建实体类
创建包com.wss.Dao,用于存放实体类。在com.wss.Dao包下创建实体类School,用于封装表单中追加的数据,即学校、城市和
院系。
School中要包含三个属性,用于封装学校、城市和院系,并给属性提供get和set方法,代码如下:
package com.wss.Dao; public class School { private String name; private String city; private String department; public School() { System.out.println("Initilization School...."); } public String getName() { System.out.println("Getting the school name"); return name; } public void setName(String name) { System.out.println("Setting the school name"); this.name = name; } public String getCity() { System.out.println("Getting the school city"); return city; } public void setCity(String city) { System.out.println("Setting the school city"); this.city = city; } public String getDepartment() { System.out.println("Getting the school department"); return department; } public void setDepartment(String department) { System.out.println("Setting the school department"); this.department = department; } }
步骤三:修改RegistAction,接受表单传入的参数
在RegistAction中,追加属性用于接受表单传入的学校、城市和院系,该属性的类型为School类型,名称为school,
并为该属性提供get和set方法。
在业务方法(execute())中输出属性school的值,代码如下:
package com.wss.action; import com.opensymphony.xwork2.ActionSupport; import com.wss.Dao.School; import com.wss.Dao.User; import com.wss.Dao.UserDao; public class RegistAction extends ActionSupport{ public RegistAction() { System.out.println("Initialization RegistAction...."); } private User user =new User(); //private User user; public User getUser() { System.out.println("Getting the getUser"); return user; } public void setUser(User user) { System.out.println("Setting the setUser"); this.user = user; } private School school; public School getSchool() { System.out.println("Getting the getSchool"); return school; } public void setSchool(School school) { System.out.println("Setting the setSchool"); this.school = school; } private String company; public void setCompany(String company) { System.out.println("Setting the company"); this.company=company; } public String execute() throws Exception{ UserDao ud =new UserDao(); System.out.println("The company is "+this.company+" The name is "+this.user.getName()+" The phone is "+this.user.getAddress()); System.out.println("The school name is "+this.school.getName()+" The city is "+this.school.getCity()+" The department is "+ this.school.getDepartment()); //if(ud.regist(user)!=0){ this.addFieldError("success", "注册成功"); return SUCCESS; //} //this.addFieldError("error", "注册失败"); //return ERROR; } }
步骤四:修改表单,设置文本框属性
在regist.jsp中,修改表单新增的3个文本框name属性值。对于域模型注入的方式,文本框name属性值应该是具有"对象名.属性名"
格式的表达式。
其中对象名指的是Action中的实体类型属性名school,属性名指的是实体类型中的各属性名(name,city,department),
代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%> <%@ page contentType="text/html;charset=gbk"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>京东商城注册页面</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <% request.setCharacterEncoding("gbk"); %> </head> <body> <center> <form action="regist" method="post"> 用户名:<input type="text" name="user.name"/><br> 密 码:<input type="password" name="user.password"/><br> 手 机:<input type="text" name="user.phone" /><br> 地 址:<input type="text" name="user.address"/><br> 公 司: <input type="text" name="company"/> <br> 学 校:<input type="text" name="school.name"/> 城 市:<input type="text" name="school.city" /> 院 系:<input type="text" name="school.department" /> <table> <tr> <td><input type="submit" value="注册"/></td> <td><input type="reset" value="重置" ></td> </tr> </table> </form> <s:fielderror /> </center> </body> </html>
步骤五:测试
重新部署项目并启动tomcat,在浏览器中输入地址:http://localhost:8080/ShopDemo/regist.jsp
效果如下图所示(当然为了稍候测试方便,我自己输入了一些信息):
点击提交,查看myeclipse的控制台,输出结果如下:
Initialization the User......
Initialization RegistAction....
Setting the company
Getting the getSchool
Initilization School....
Setting the setSchool
Setting the school city
Getting the getSchool
Setting the school department
Getting the getSchool
Setting the school name
Getting the getUser
Setting the address
Getting the getUser
Setting the name
Getting the getUser
Setting the password
Getting the getUser
Setting the phone
Getting the name
Getting the address
The company is 公司 The name is good The phone is wrwer
Getting the school name
Getting the school city
Getting the school department
The school name is xuexiao The city is beiijng The department is shuxue
控制台输出的顺序可以证明代码的执行顺序为:实例化Action-->实例化User并注入参数-->调用set方法注入User对象-->调用业务
方法。
在这里,private User user =new User();和private School school;不一样,school只是一个引用,并没有用new创建出对象,
所以在对school的各属性name、city和department用set方法注入时,用getSchool方法得到school对象时(Getting the getSchool),还没有school对象的存在,此时调用School的构造函数进行初始化创建school对象;然后通过school对象对其各
属性用setName....方法对school的各属性进行注入。