一. 复杂对象传递
1. 视图给action中复杂的对象属性传参
假设我们有这样子的一个User对象:
private int id;
private String username;
private String password;
private Integer age;
private char sex;
private Address address;
这是Address对象的两个属性:
private String homeAddress;
private String companyAddress;
get和set方法我就不写了,那么在传递这样子的一个对象的时候怎么才能更方便呢?
首先看我们的表单要改写成这个样子:
<form action="/web/test/user.action" method="post">
Id:<input name="user.id" /><br />
UserName:<input name="user.username" /><br />
Password:<input name="user.password" type="password" /><br />
Sex:<input name="user.sex" /><br />
Age:<input name="user.age" /><br />
home add:<input name="user.address.homeAddress" /><br />
company add:<input name="user.address.companyAddress" /><br />
<input type="submit" name="method:add" value="添加" />
</form>
然后在Action中这样子写:
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String add() {
UserManager userManager = new UserManager();
userManager.add(user);
return "add_success";
}
关于UserManager的数据库连接层代码就不写了。
使用user.username和user.address.homeAddress就可以轻松获取响应的表单值了。
2. action给视图传递复杂类型数据
修改提交成功的页面:
添加成功!<br />
user:<s:property value="user"/><br />
Id:<s:property value="user.id"/><br />
UserName:<s:property value="user.username"/><br />
Password:<s:property value="user.password"/><br />
Sex:<s:property value="user.sex"/><br />
Age:<s:property value="user.age"/><br />
Home Add:<s:property value="user.address.homeAddress"/><br />
Company Add:<s:property value="user.address.companyAddress"/><br />
就可以获取到刚才提交的值显示出来。
接下来来写一个查询的功能。
首先是UserManager的查询方法:
public User findUserById(int userId) {
User user = null;
Connection conn = DB.getConnection();
PreparedStatement prst = null;
ResultSet rs = null;
String sql = "select * from t_user where id=?";
try {
prst = conn.prepareStatement(sql);
prst.setInt(1, userId);
rs = prst.executeQuery();
if (!rs.next()) {
throw new SQLException("没有找到记录");
}
user = new User();
user.setId(userId);
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setAge(rs.getInt("age"));
user.setSex(rs.getString("sex").charAt(0));
} catch (SQLException e) {
e.printStackTrace();
} finally {
DB.closeConnection(conn);
}
return user;
}
然后是查询界面,这里使用了一点javascript的脚本:
<script type="text/javascript">
function query() {
var pam = document.getElementById("pam");
location = "/web/test/user.action?method:query&user.id=" + pam.value;
}
</script>
</head>
<body>
<a href="/web/test/user.action?method:addInput">添加</a><br/>
<input id="pam"><input type="button" value="查询" οnclick="query()">
</body>
在strust配置文件中加入:
<result>/success.jsp</result>
Action中的查询方法:
public String query() {
UserManager userManager = new UserManager();
if (user.getId() != 0) {
User u = userManager.findUserById(user.getId());
if (u != null) {
ActionContext.getContext().put("user", u);
// ServletActionContext.getRequest().getSession()
// .setAttribute("user", u);
// ActionContext.getContext().getSession().put("user", u);
}
}
return "success";
}
注意最后需要返回的是"success",这样才能跳转到success.jsp页面。
最后是success.jsp页面显示:
<br /> UserName:<s:property value="#session.user.username"/>
<br /> Password:<s:property value="#session['user'].password"/>
<br /> sex:<s:property value="#session.user.sex"/>
<br /> Age:<s:property value="#session.user.age"/>
<!--
<br /> UserName:<s:property value="#user.username"/>
<br /> Password:<s:property value="#user.password"/>
<br /> sex:<s:property value="#user.sex"/>
<br /> Age:<s:property value="#user.age"/>
-->
注释中用的是Action查询方法中后面两种的显示方式。
3. 传递集合数据
当查出来的数据是一个集合时,该如何传递呢?我们假设从服务器查到了一部分数据,这里用queryAll来模拟:
public String queryAll() {
username = "张三";
password = "123";
List<User> list = new ArrayList<User>();
for (int i = 0; i < 10; i++) {
User u = new User();
u.setUsername("用户" + i);
u.setPassword("密码" + i);
u.setSex(i % 2 == 0 ? '男' : '女');
u.setAge(new Random().nextInt(100));
list.add(u);
}
ActionContext.getContext().put("list", list);
return "list";
}
username和password是新加的action的两个属性,记得要写get和set方法。我们看看再jsp页面中是如何显示的:
<body>
查询集合<br />
循环外部:
<s:property value="username"/>,
<s:property value="password"/><br />
<s:iterator value="#list" var="user">
循环内部
UserName:<s:property value="username"/>,
Password:<s:property value="#user.password"/>,
Sex:<s:property value="sex"/>,
Age:<s:property value="age"/><br />
再循环内部访问外部对象:<br />
<s:property value="#root[1].username"/>,
<s:property value="#root[1].password"/><br />
</s:iterator>
循环外部:
<s:property value="username"/>,
<s:property value="password"/><br />
</body>
要遍历结合我们用到了iterator标签,然后使用value="属性名"就可以访问到User的值了。那么如何访问到Action中的username和password的值呢?我们可以看到在循环内部,无论使用value="username"还是value="#user.username"访问的都是内部的user的属性,访问外部的属性需要使用value="#root[1].username"来显示。实际上,这里存储这些变量的是一个栈,开始的username和password被放在最底部,当list集合进来时,一个新的user对象被放在了之前Action的上面,那么要想访问之前的username和password需要使用根部元素root加下标[1]才可以访问得到。