Примечание: Я попытался объединить ответы, чтобы составить полный список. Я упомянул имена, где это уместно, чтобы дать кредит, где это причитается.
Есть много способов решить эту проблему, с плюсами / минусами, связанными с каждым:
Чистое решение JSP
Как упоминалось выше в ScArcher2, очень простое и простое решение проблемы - реализовать его непосредственно в JSP следующим образом:
<c:set var="ageTotal" value="${0}" />
<c:forEach var="person" items="${personList}">
<c:set var="ageTotal" value="${ageTotal + person.age}" />
<tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${ageTotal}
Проблема с этим решением заключается в том, что JSP начинает сбивать с толку до такой степени, что вы с таким же успехом могли бы вводить скрипты. Если вы ожидаете, что каждый, кто заглянет на страницу, сможет следовать элементарной логике, то это хороший выбор.
Чистый раствор EL
Если вы уже используете EL 3.0 (Java EE 7 / Servlet 3.1), используйте новую поддержку потоков и лямбд :
<c:forEach var="person" items="${personList}">
<tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${personList.stream().map(person -> person.age).sum()}
Функции JSP EL
Еще один способ вывести итоговое значение без введения кода скрипта в JSP - это использовать функцию EL. EL-функции позволяют вам вызывать открытый статический метод в открытом классе. Например, если вы хотите перебрать свою коллекцию и суммировать значения, вы можете определить публичный статический метод с именем sum (List people) в публичном классе, возможно, под названием PersonUtils. В вашем файле tld вы должны разместить следующую декларацию:
<function>
<name>sum</name>
<function-class>com.example.PersonUtils</function-class>
<function-signature>int sum(java.util.List people)</function-signature>
</function>
В вашем JSP вы бы написали:
<%@ taglib prefix="f" uri="/your-tld-uri"%>
...
<c:out value="${f:sum(personList)}"/>
Функции JSP EL имеют несколько преимуществ. Они позволяют использовать существующие методы Java без необходимости кодирования для определенного пользовательского интерфейса (библиотеки пользовательских тегов). Они также компактны и не смущают не ориентированного на программирование человека.
Пользовательский тег
Еще один вариант - свернуть свой собственный тег. Эта опция будет включать в себя большую часть настроек, но даст вам то, что вы, по-моему, ищете, абсолютно без скриплетов. Хороший учебник по использованию простых пользовательских тегов можно найти по адресу http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701
Включенные шаги включают создание подкласса TagSupport:
public PersonSumTag extends TagSupport {
private List personList;
public List getPersonList(){
return personList;
}
public void setPersonList(List personList){
this.personList = personList;
}
public int doStartTag() throws JspException {
try {
int sum = 0;
for(Iterator it = personList.iterator(); it.hasNext()){
Person p = (Person)it.next();
sum+=p.getAge();
}
pageContext.getOut().print(""+sum);
} catch (Exception ex) {
throw new JspTagException("SimpleTag: " +
ex.getMessage());
}
return SKIP_BODY;
}
public int doEndTag() {
return EVAL_PAGE;
}
}
Определение тега в файле tld:
<tag>
<name>personSum</name>
<tag-class>example.PersonSumTag</tag-class>
<body-content>empty</body-content>
...
<attribute>
<name>personList</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.util.List</type>
</attribute>
...
</tag>
Объявите taglib в верхней части вашего JSP:
<%@ taglib uri="/you-taglib-uri" prefix="p" %>
и используйте тег:
<c:forEach var="person" items="${personList}">
<tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
<p:personSum personList="${personList}"/>
Показать тег
Как упоминалось ранее zmf, вы также можете использовать тег display, хотя вам нужно будет включить соответствующие библиотеки:
http://displaytag.sourceforge.net/11/tut_basic.html