Dón*_*nal 17 foreach jsp jstl sum totals
我有一个这样的Java bean:
class Person {
int age;
String name;
}
Run Code Online (Sandbox Code Playgroud)
我想在JSP中迭代这些bean的集合,在HTML表格行中显示每个人,在表格的最后一行我想显示所有年龄段的总数.
生成表行的代码如下所示:
<c:forEach var="person" items="${personList}">
<tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
Run Code Online (Sandbox Code Playgroud)
但是,我很难找到一种方法来计算最终行中显示的年龄总计,而不需要求助于scriptlet代码,任何建议?
Jon*_*rik 38
注意:我尝试将答案组合成一个综合列表.我提到了适当的名字,以便在到期时提供信贷.
有很多方法可以解决这个问题,每个方面都有利弊:
纯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}
Run Code Online (Sandbox Code Playgroud)
这个解决方案的问题在于JSP变得令人困惑,以至于您可能已经引入了scriplet.如果您预计每个看页面的人都能够遵循现有的基本逻辑,那么这是一个不错的选择.
纯EL解决方案
如果您已经使用EL 3.0(Java EE 7/Servlet 3.1),请使用对流和lambdas的新支持:
<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()}
Run Code Online (Sandbox Code Playgroud)
JSP EL函数
在不将scriplet代码引入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>
Run Code Online (Sandbox Code Playgroud)
在你的JSP中你会写:
<%@ taglib prefix="f" uri="/your-tld-uri"%>
...
<c:out value="${f:sum(personList)}"/>
Run Code Online (Sandbox Code Playgroud)
JSP EL函数有一些好处.它们允许您使用现有的Java方法,而无需编写特定的UI(自定义标记库).它们也很紧凑,不会混淆非编程人员.
自定义标签
另一种选择是推出自己的自定义标签.这个选项将涉及最多的设置,但会给你我认为你真正寻找的东西,绝对没有scriptlets.有关使用简单自定义标签的精彩教程,请访问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;
}
}
Run Code Online (Sandbox Code Playgroud)
在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>
Run Code Online (Sandbox Code Playgroud)
在JSP的顶部声明taglib:
<%@ taglib uri="/you-taglib-uri" prefix="p" %>
Run Code Online (Sandbox Code Playgroud)
并使用标签:
<c:forEach var="person" items="${personList}">
<tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
<p:personSum personList="${personList}"/>
Run Code Online (Sandbox Code Playgroud)
显示标签
正如前面提到的zmf,你也可以使用display标签,尽管你需要包含适当的库:
http://displaytag.sourceforge.net/11/tut_basic.html
你想把所有的年龄加起来吗?
你可以在你的控制器中计算它并且只在jsp中显示结果。
您可以编写自定义标记来进行计算。
您可以像这样使用jstl在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}
Run Code Online (Sandbox Code Playgroud)