action接收请求参数
在web开发中,去接收请求参数来获得表单信息非常的常见,自己也总结整理了有关Struts2通过action接收请求参数的几种方法。
Struts2 提供三种数据封装的方式:
(1) Action 本身作为model对象,通过成员setter封装
(2) 创建独立model对象,页面通过ognl表达式封装
(3) 使用ModelDriven接口,对请求数据进行封装(推荐)
下面我们来讲解第一种:
(1) Action类本身作为model对象通过成员的setter方法封装(属性驱动)
setXxx()的xxx必须与请求的参数名一样。就是指和form表单中的name对应的属性要一致
action类的代码:
import java.util.Arrays; import com.ssh.struts2.model.User; import com.opensymphony.xwork2.ActionSupport; /* * 通过这种方法最简单,但也有缺点如果要把数据封装到model对象中然后传递给业务层和数据层 * 还需要单独定义model对象进行传递数据 */ public class RegisterAction1 extends ActionSupport { private String username; private String [] hobby; @Override public String execute() throws Exception { //获取表单的数据 System.out.println("用户名是:"+username); System.out.println("兴趣爱好是:"+Arrays.toString(hobby)); return null; } //这里必须提供set方法,get方法可有可无 public void setUsername(String username) { this.username = username; } public void setHobby(String[] hobby) { this.hobby = hobby; } } /*当你在界面中用户名输入:zhangsan,兴趣爱好选择:体育和读书那么运行结果如下: * 用户名是:zhangsan * 兴趣爱好是:[sport, read] */
struts.xml
<?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> <package name="default" extends="struts-default"> <action name="register1" class="com.ssh.struts2.action.RegisterAction1"> </action> </package> </struts>
register.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> </head> <body> <h4>注册表单1 </h4> <form action="${pageContext.request.contextPath }/register1.action" method="post"> 用户名:<input type="text" name="username"><br/> 爱好:<input type="checkbox" name="hobby" value="sport">体育 <input type="checkbox" name="hobby" value="music">音乐 <input type="checkbox" name="hobby" value="read">读书 <br/> <input type="submit" value="注册"> </form> </body> </html>
网页:
(2) 创建独立model对象,页面通过ognl表达式封装
该方法首先要创建一个专门的领域对象进行封装
User领域对象
import java.util.Arrays; public class User { private String username; private String [] hobby; //为这两个常量提供set和get方法和toString方法
Action类
import com.ssh.struts2.model.User; import com.opensymphony.xwork2.ActionSupport; public class RegisterAction2 extends ActionSupport{ //直接定义model对象 private User user; @Override public String execute() throws Exception { System.out.println("user:"+user); return NONE; } /* * 必须提供get方法 * 封装第一个参数 创建一个新的User对象 然后把username属性封装到这个创建的user对象中 User user =new User();user.setUserName(""); * 封装第二个参数 已经存在user对象 User user =getUser(); user.setPassword("); */ public User getUser() { return user; } public void setUser(User user) { this.user = user; } } /* * 如果jsp界面输入:用户名:aa 兴趣爱好:体育读书 * 后台输出:user:User [username=aa, hobby=[sport, music]] */
register.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <html> 3 <head> 4 </head> 5 <body> 6 <!-- 用ognl表达式要注意的一点就是,标签的属性name在取名字的时候是:领域对象.属性 7 user.username这里user是具体的对象,username是领域对象的属性--> 8 <h4>注册表单1 </h4> 9 <form action="${pageContext.request.contextPath }/register2.action" method="post"> 10 用户名:<input type="text" name="user.username"><br/> 11 爱好:<input type="checkbox" name="user.hobby" value="sport">体育 12 <input type="checkbox" name="user.hobby" value="music">音乐 13 <input type="checkbox" name="user.hobby" value="read">读书 <br/> 14 <input type="submit" value="注册"> 15 </form> 16 </body> 17 </html>
说明:struts2首先通过反射技术调用User的默认构造器创建User对象,然后通过反射技术调用User中与请求参数同名的属性的setter方法来获取请求参数值。在这里需要注意的一点是:User对象一定要有默认的构造器。
采用复合类型接收请求参数的好处,可以减少action中的setter和getter方法,同时可以把相应的属性组合成一个类,这样使代码更好清晰,代码有更好的结构。
(3)使用ModelDriven接口,对请求数据进行封装
第三种方法比较方便,和方法(1)不同在于它也要先创建一个领域对象类进行对象的封装。其它和方法(1)一样
Action类
import com.ssh.struts2.model.User; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; //实现ModelDriven<User>接口 public class RegisterAction3 extends ActionSupport implements ModelDriven<User> { /** * 方式三 使用模型驱动 */ //这里需要注意,方法2中的user对象不需要自己创建,而这里必须手动初始化 private User user =new User(); public User getModel() { return user; } @Override public String execute() throws Exception { System.out.println("user:"+user); return NONE; } } /* * 如果jsp界面输入:用户名:aa 兴趣爱好:体育读书 * 后台输出:user:User [username=aa, hobby=[sport, music]] */
最后我们来思考两个问题,也是常见的笔面试题:
问题一:Action封装数据会不会有线程问题?
问题二:在使用第一种方式进行封装的时候数据封装到Action 属性中不能把Action传递给业务层数据如何传递?
谢谢大家浏览,欢迎大家指点!