想创建并使用一个支持java.util.List的form属性,想通过一个方法得到整个列表的数据以及使用索引属性得到列表中指定的值。
解决方案
将form属性创建为支持java.util.List 的索引属性,如例5.4所示。
例5.4:支持列表的form属性
package com.oreilly.strutsckbk.ch05;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
public class ListForm extends ActionForm {
private int size = 3;
private List friends = new ArrayList(size);
public List getFriends() {
return friends;
}
public String getFriend(int index) {
return (String) friends.get(index);
}
public void setFriend(int index, String name) {
friends.set(index, name);
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
// prepopulate the list with empty strings
friends = new ArrayList();
for (int i=0; i<size;i++) friends.add("");
}
}
例5.5(list_form_test.jsp)显示了如何从JSP页面获得属性值。通过访问作为索引属性的独立的元素,创建表单。通过遍历列表输出结果。
例5.5:得到支持列表的form属性
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<head>
<title>Struts Cookbook - Chapter 5 : List-backed Form Property</title>
</head>
<body>
<h2>List Form Test</h2>
<html:form action="/ProcessListForm">
Who are your 3 friends:<br />
Friend 1: <html:text property="friend[0]"/><br />
Friend 2: <html:text property="friend[1]"/><br />
Friend 3: <html:text property="friend[2]"/><br />
<html:submit/>
</html:form>
<hr />
<c:forEach var="item" items="${ListForm.friends}">
<c:out value="${item}"/><br />
</c:forEach>
</body>
</html>
讨论
有时您需要一个form属性来表示一组值而不是一个值。值类型可以很简单,就像String或者数字一样,也可以很复杂,有其他类型构成。ActionForm可以有简单或者复杂的由java.util.List实现支持的类型。
那么,如何能从HTML表单获得支持列表的属性呢?首先,您要提供getter和setter方法,这些方法遵照JavaBean对于索引属性的约定:
public Foo getFoo(int index);
public void setFoo(int index, Foo foo);
只要属性遵照这一约定,就能够得到其值,不管底层实现如何。假如属性值在存储java.util.List实现中,比如java.util.ArrayList,那么getter方法会调用list.get(index)并且setter方法会调用list.set(index,obj)。
尽管List不同于数组,可以变化大小的,但是您还是需要保证getter和setter方法不会尝试着访问其值超过List大小的索引位置的值。否则会抛出IndexOutOfBoundsException异常。您可以在ActionForm的reset()方法中预先加载List,或者您可以动态的按需改变列表的大小以适应getter和setter方法:
public Foo getFoo(int index) {
if (index >= list.size( )) {
list.add(new Foo( ));
}
return (Foo) list.get(index)
}
public void setFoo(int index, Foo foo) {
if (index < list.size()) {
list.set(index, foo);
}
else {
list.add(index, foo);
}
}