struts2 二: 参数封装
封装请求正文到对象中(非常重要)
1、静态参数封装
在struts.xml配置文件中,给动作类注入值。调用的是setter方法。
struts.xml的编写:
<action name="action1" class="com.itheima.web.action.Demo1Action" method="addUser">
<param name="username">张三</param>
<param name="age">18</param>
</action>
动作类中编写的:
/**
* 静态参数封装
*/
public class Demo1Action{
private String username;
private int age;
public String addUser(){
System.out.println(username+","+age);
return null;//不返回任何结果视图 NONE常量
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
原因:是由一个staticParams的拦截器完成注入的。
2、动态参数封装:开发时用到的
通过用户的表单封装请求正文参数。
2.1、动作类作为实体模型
实体模型:Entity,对应数据库中表的记录(注意类对应的是表结构,而对象对应的是一条记录)
<!-- 动态参数封装的第一种形式的配置 --> <action name="action2" class="com.itheima.web.action.Demo2Action" method="addUser"> </action>
import com.opensymphony.xwork2.ActionSupport;
/**
* 动态参数封装,第一种情况:
* 数据模型与动作类写在一起
* @author zhy
*
*/
public class Demo2Action extends ActionSupport {
private String username;
private int age;
public String addUser(){
System.out.println(username+","+age);
return null;//不返回任何结果视图 NONE常量
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>动态参数封装</title> </head> <body> <form action="${pageContext.request.contextPath}/action2.action" method="post"> <%--表单中的name属性取值必须和动作类中数据模型的set方法后面的名称一致。 --%> 用户名:<input type="text" name="username" /><br/> 年龄:<input type="text" name="age"/><br/> <input type="submit" value="提交" /> </form> </body> </html>
原因:是由params拦截器完成的。
2.2、动作类和实体模型分开
配置文件代码:
package com.itheima.web.action;
import com.itheima.domain.User;
import com.opensymphony.xwork2.ActionSupport;
/**
* 动态参数封装,第二种情况:
* 数据模型与动作类分开写
* @author zhy
*
*/
public class Demo3Action extends ActionSupport {
//定义数据模型对象(可以实例化也可以不实例化)
private User user = new User();
public String addUser(){
System.out.println(user.getUsername()+","+user.getAge());
return null;//不返回任何结果视图 NONE常量
}
public User getUser() {
System.out.println("getUser");
return user;
}
public void setUser(User user) {
System.out.println("setUser");
this.user = user;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>动态参数封装</title> </head> <body> <form action="${pageContext.request.contextPath}/action3.action" method="post"> <%--表单中的name属性取值必须和动作类中数据模型的set方法后面的名称一致。 --%> 用户名:<input type="text" name="user.username" /><br/> 年龄:<input type="text" name="user.age"/><br/> <input type="submit" value="提交" /> </form> </body> </html>
问题:
由于我们没有初始化user对象,默认为null,一调用setUser方法,就空指针异常了。但是框架却封装进去值了。
原因:
框架会get判断有误模型方法,有: 就再get一次拿到对象封装参数 没有: 创建一个对象set进动作类,之后再get对象封装参数。
2.3、模型驱动:建立动作类和模型分开的前提下(开发中采用的方式)
1 <!-- 动态参数封装的第三种形式的配置(模型驱动) --> 2 <action name="action4" class="com.itheima.web.action.Demo4Action" method="addUser"></action> 3 </package>
1 /** 2 * 动态参数封装,第三种情况:模型驱动 3 * 要想使用模型驱动,必须数据模型与动作类分开写 4 * 实现模型驱动的步骤: 5 * 1.实现一个ModelDriven的接口 6 * 2.实现接口中的抽象方法getModel() 7 * 3.在使用模型驱动的时候,数据模型必须由我们自己来实例化 8 * 9 * 是由一个ModelDriven的拦截器为我们做的 10 * 11 * 实际开发中采用的方式 12 * @author zhy 13 * 14 */ 15 public class Demo4Action extends ActionSupport implements ModelDriven<User>{ 16 17 //定义数据模型对象 18 private User user = new User() ;//使用模型驱动,必须自己实例化模型对象 19 20 21 //该方法返回的是数据模型 22 public User getModel() { 23 return user; 24 } 25 26 public String addUser(){ 27 System.out.println(user.getUsername()+","+user.getAge()); 28 return null;//不返回任何结果视图 NONE常量 29 } 30 31 public User getUser() { 32 return user; 33 } 34 35 public void setUser(User user) { 36 this.user = user; 37 } 38 39 }
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>动态参数封装</title> 6 </head> 7 <body> 8 <form action="${pageContext.request.contextPath}/action4.action" method="post"> 9 <%--需要注意name属性的取值,已经不是一个普通的字符串了 --%> 10 用户名:<input type="text" name="username" /><br/> 11 年龄:<input type="text" name="age"/><br/> 12 <input type="submit" value="提交" /> 13 </form> 14 </body> 15 </html>
原因:是由一个modelDriven拦截器做的, 先判断是否是想 ModeDriven接口,再看是否返回了模型对象,不是则跳过
是: 压入 valueStack栈顶, 之后由params 拦截器封装参数。