<%@ page contentType="text/html;charset=UTF-8" language="java" %> 数据封装 - Struts2 学习

📦 数据封装 - 属性驱动 vs 模型驱动

📝 本节要点: 掌握 Struts2 两种数据封装方式,将请求参数封装到 Java 对象

1. 两种封装方式对比

方式 实现 适用场景
属性驱动 Action 中定义属性 + getter/setter 简单场景,属性较少
模型驱动 实现 ModelDriven 接口 复杂对象,表单字段多

2. 方式一:属性驱动 (Property Driven)

2.1 基本属性封装

/**
 * 直接在 Action 中定义属性
 * 表单: <input name="username"> 会自动调用 setUsername()
 */
public class UserAction extends ActionSupport {
    
    // Struts2 自动调用 setter 注入参数
    private String username;
    private String email;
    private Integer age;
    
    @Override
    public String execute() {
        System.out.println(username + " - " + email + " - " + age);
        return SUCCESS;
    }
    
    // 必须提供 setter 和 getter
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
}

2.2 复杂属性 (嵌套对象)

表单中的 user.username 会自动调用 setUser(用户对象).setUsername()

// Action
private User user;  // 包含 username, email 属性的对象

// 表单
<input name="user.username"/>
<input name="user.email"/>

3. 方式二:模型驱动 (ModelDriven)

💡 推荐: 对于复杂表单,使用模型驱动更清晰,Action 和 Model 分离
import com.opensymphony.xwork2.ModelDriven;

/**
 * 实现 ModelDriven 接口
 * 需要:
 * 1. 实现 getModel() 方法
 * 2. 泛型指定模型类型
 */
public class UserAction extends ActionSupport implements ModelDriven<User> {
    
    // 模型对象
    private User user = new User();
    
    /**
     * 返回模型对象
     * Struts2 会把参数注入到返回的对象中
     */
    @Override
    public User getModel() {
        return user;
    }
    
    @Override
    public String execute() {
        // 直接使用 user 对象
        System.out.println(user.getUsername());
        return SUCCESS;
    }
}

4. List/Map 属性封装

// Action - 接收 List
private List<User> users;
public void setUsers(List<User> users) { this.users = users; }
public List<User> getUsers() { return users; }

// 页面表单 - users[0].username, users[1].username
<input name="users[0].username" value="张三"/>
<input name="users[1].username" value="李四"/>

// Action - 接收 Map
private Map<String, User> userMap;
<input name="userMap['one'].username"/>

5. 封装流程图

请求参数 → Action  setter 方法 → 属性赋值
                ↓
      实现 ModelDriven → getModel() → 模型对象赋值
                ↓
             值栈 (Value Stack)
下一节:文件上传 → ← 返回首页