七、Struts2框架的資料封裝
什麼叫框架的資料封裝?
就是將原本需要使用Servlet的Api手動去解析請求引數,然後封裝成model的操作交給了Struts2框架來完成。Struts2的框架採用了攔截器來完成資料的封裝。
兩類資料封裝的方式
1.屬性驅動方式
提供對應屬性的set方法進行資料的封裝。
表單的哪些屬性需要封裝資料,那麼在對應的Action類中提供該屬性的set方法即可。
表單中的資料提交,最終找到Action類中的setXxx的方法,最後賦值給全域性變數。
例如:
package blog.csdn.net.mchenys;
import com.opensymphony.xwork2. ActionSupport;
/**
* 屬性驅動
*
* @author mChenys
*/
public class Regist1Action extends ActionSupport {
private static final long serialVersionUID = -966487869258031548L;
//定義屬性,名稱需要保持和jsp頁面的表單name屬性名一直
private String username;
private String password;
private Integer age;
//提供get方法
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setAge(Integer age) {
this.age = age;
}
public String execute() throws Exception {
//直接使用預定義的屬性
System.out.println(username + " " + password + " " + age);
return NONE;
}
}
jsp頁面
<form action="${ pageContext.request.contextPath }/regist1.action"
method="post">
姓名:<input type="text" name="username" /><br />
密碼:<input type="password" name="password" /><br />
年齡:<input type="text" name="age" /><br />
<input type="submit" value="註冊" />
</form>
action的配置
<action name="regist1" class="blog.csdn.net.mchenys.Regist1Action"/>
注意:
屬性驅動這種方式不是特別好,因為屬性特別多,就要提供特別多的set方法,而且還需要手動將資料存入到物件中。
這種情況下,Action類就相當於一個JavaBean,就沒有體現出MVC的思想,Action類又封裝資料,又接收請求處理,耦合性較高。
屬性驅動還有另一種方式:
在頁面中使用OGNL表示式進行資料的封裝,就可以直接把屬性封裝到某一個JavaBean的物件中。
另外需要在Action類中定義一個JavaBean,並且提供get/set方法;
然後頁面中的表單name屬性值需要使用OGNL的方式,表單中的寫法:<input type="text" name="user.username">
其中點(.)前面的user對應的是Action類中宣告的javabean的名稱,而username則對應該javabean中的屬性名
例如:
package blog.csdn.net.mchenys;
import com.opensymphony.xwork2.ActionSupport;
import blog.csdn.net.mchenys.domain.User;
/**
* 屬性驅動方式,把資料封裝到JavaBean的物件中
*
* @author mChenys
*/
public class Regist2Action extends ActionSupport {
private static final long serialVersionUID = 6556880331550390473L;
// 宣告javabean物件,也可以同時初始化好
private User user;
// 注意:通過javabean的這種方式,需要提供get和set方法
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() throws Exception {
System.out.println(user);
return NONE;
}
}
javabean編寫
public class User {
private String username;
private String password;
private Integer age;
//get/set方法...
}
然後修改表單的name屬性如下:
<form action="${ pageContext.request.contextPath }/regist2.action"
method="post">
姓名:<input type="text" name="user.username" /><br />
密碼:<input type="password" name="user.password" /><br />
年齡:<input type="text" name="user.age" /><br />
<input type="submit" value="註冊" />
</form>
注意:
Action類中什麼的javabean物件必須要提供get和set方法,如果已經手動例項化了該javabean物件,那麼set方法可以不用寫.
2.模型驅動方式
使用模型驅動的方式,也可以把表單中的資料直接封裝到一個JavaBean的物件中,並且表單的寫法和之前的寫法沒有區別!
編寫的頁面不需要任何變化,正常編寫name屬性的值, 模型驅動的編寫步驟:
- Action類需手動例項化JavaBean,即:private User user = new User();
- Action類必須實現
ModelDriven<T>
介面,並實現getModel()的方法,然後在getModel()方法中返回user即可.
例如:
package blog.csdn.net.mchenys;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import blog.csdn.net.mchenys.domain.User;
/**
* 模型驅動的方式
*
* @author mChenys
*
*/
public class Regist3Action extends ActionSupport implements ModelDriven<User> {
private static final long serialVersionUID = 6556880331550390473L;
// 必須宣告和例項化javabean物件
private User user = new User();
// 必須實現該方法
public User getModel() {
return user;
}
public String execute() throws Exception {
System.out.println(user);
return NONE;
}
}
ok,jsp頁面不需要額外處理,只需要保持name屬性=javabean的屬性名即可,然後配置下action就可以了.
如何把資料封裝到集合中
Struts2還可以實現將資料封裝到集合中(集合型別 Collection 、Map介面等),這個就需要修改jsp頁面的name屬性了,
1.對於list集合的處理:
在Action中的寫法,需要提供products的集合,並且提供get和set方法。例如:
package blog.csdn.net.mchenys;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import blog.csdn.net.mchenys.domain.User;
/**
* 把資料封裝到List集合中
*
* @author mChenys
*
*/
public class Regist4Action extends ActionSupport {
private static final long serialVersionUID = 6556880331550390473L;
//宣告javabean集合
private List<User> list;
//提供get/set方法
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
public String execute() throws Exception {
for (User user : list) {
System.out.println(user);
}
return NONE;
}
}
因為Collection介面都會有下標值,頁面的寫法例如<input type="text" name="list[0].username" />
,其中list代表的是Action類中宣告的list集合,[0]表示list集合的第一個位置,而username表示的是javabean中的屬性名。jsp頁面如下:
<form action="${ pageContext.request.contextPath }/regist4.action" method="post">
姓名:<input type="text" name="list[0].username" /><br/>
密碼:<input type="password" name="list[0].password" /><br/>
年齡:<input type="password" name="list[0].age" /><br/>
姓名:<input type="text" name="list[1].username" /><br/>
密碼:<input type="password" name="list[1].password" /><br/>
年齡:<input type="password" name="list[1].age" /><br/>
<input type="submit" value="註冊" />
</form>
2.對於Map的處理:
Action中提供map集合,並且提供get和set方法,例如:
package blog.csdn.net.mchenys;
import java.util.Map;
import com.opensymphony.xwork2.ActionSupport;
import blog.csdn.net.mchenys.domain.User;
/**
* 把資料封裝到Map集合中
*
* @author mChenys
*
*/
public class Regist5Action extends ActionSupport {
private static final long serialVersionUID = 6556880331550390473L;
// 宣告map集合
private Map<String, User> map;
// 提供get/set方法
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
public String execute() throws Exception {
System.out.println(map);
return NONE;
}
}
Map集合是鍵值對的形式,頁面的寫法例如<input type="text" name="map['one'].username" />
,其中map表示Action類中宣告的map集合,one代表map集合的key而username代表javabean的屬性名稱。jsp頁面如下:
<form action="${ pageContext.request.contextPath }/regist5.action" method="post">
姓名:<input type="text" name="map['one'].username" /><br/>
密碼:<input type="password" name="map['one'].password" /><br/>
年齡:<input type="password" name="map['one'].age" /><br/>
姓名:<input type="text" name="map['two'].username" /><br/>
密碼:<input type="password" name="map['two'].password" /><br/>
年齡:<input type="password" name="map['two'].age" /><br/>
<input type="submit" value="註冊" />
</form>