我有一个Java bean是这样的:
class Person {
int age;
String name;
}
我想遍历这些bean的集合在一个JSP,显示一个HTML表格行的每个人,并在表的最后一排,我想显示的总所有年龄段的。
生成表行的代码会是这个样子:
<c:forEach var="person" items="${personList}">
<tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
不过,我在努力寻找一种方法来计算总的年龄将在最后一行中显示,而不诉诸scriptlet代码可以,有什么建议?
注:我试图合并的答案做一个全面的列表。 我提到的名字酌情给予信贷,这是因为。
有很多方法来解决这个问题,与每个相关的优点/缺点:
纯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变得扑朔迷离的地步,你可能也有介绍scriplets。 如果预计每个人都在看网页就可以按照基本的逻辑目前它是一个不错的选择。
纯EL解决方案
如果你已经对EL 3.0(Java EE的7 / Servlet的3.1),使用新的支持流和lambda表达式 :
<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功能
另一种方式来输出,而不会引入scriplet代码加入到JSP总是使用EL函数。 EL功能允许您呼叫的公共类的公共静态方法。 例如,如果你想遍历您的收藏和在一个公共类,也许叫PersonUtils综上所述,你可以定义一个公共静态方法称为sum(列表)的值。 在您的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方法,而无需代码到一个特定的UI(用户自定义标签库)。 他们也很紧凑,不会混淆非编程导向的人。
自定义标记
另一个选择是推出自己的自定义标签。 此选项将涉及大多数设置,但会给你什么,我认为你是esentially寻找的,是绝对没有小脚本。 使用简单的自定义标签的一个很好的教程,可以发现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>
声明你的JSP顶部的taglib:
<%@ 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前面提到的,你也可以使用显示标签,虽然你将需要包括相应的库:
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}
看看显示的标签。 http://displaytag.sourceforge.net/11/tut_basic.html
ScArcher2具有最简单的解决方案 。 如果你想要的东西尽可能紧凑,你可以创建一个标签库中有一个“总和”功能。 就像是:
class MySum {
public double sum(List list) {...}
}
在您的TLD:
<function>
<name>sum</name>
<function-class>my.MySum</function-class>
<function-signature>double sum(List)</function-signature>
</function>
在你的JSP,你会碰到这样的:
<%@ taglib uri="/myfunc" prefix="f" %>
${f:sum(personList)}
这是一个有点哈克,但在你的控制器代码,你可以只创建一个虚拟的Person对象,在它的总!
你是如何检索您的对象? HTML可用于设定<TFOOT>其中将坐于有任何数据的底部元件,因此你可以只从Person对象和输出在页面上分别设置总原样而不JSP页面上的任何计算。
您可以根据以下使用JSTL遍历集合
<c:forEach items="${numList}" var="item">
${item}
</c:forEach>
如果它是一个地图,你可以在下面做
<c:forEach items="${numMap}" var="entry">
${entry.key},${entry.value}<br/>
</c:forEach>
计算合计/或其他摘要控制器 - 不是在JSP - 真的是强烈优选的。
使用而不是试图做太多的JSP或JSTL Java代码与一个MVC方法,例如Spring MVC框架; 这些语言做显著计算薄弱和缓慢,使你的JSP页面更加不明朗。
例:
class PersonList_Controller implements Controller {
...
protected void renderModel (List<Person> items, Map model) {
int totalAge = 0;
for (Person person : items) {
totalAge += person.getAge();
}
model.put("items", items);
model.put("totalAge", totalAge);
}
}
设计决策英明 - 任何地方总要求,可以想见,下个月扩展到需要的平均值,中位数,标准偏差。
JSTL计算和总结几乎没有一起举行,在刚开始的总计。 你真的会想,以满足JSTL任何进一步的总结要求? 我认为答案是否定的 - 这所以正确的设计决策是在控制器来计算,因为同样的/更简单,绝对更合理,要求扩展。