2008-09-19 14 views
16

Ich habe eine Java-Bean wie folgt aus:berechnen Summe aller Zahlen in c: foreach-Schleife

class Person { 
    int age; 
    String name; 
} 

Ich möchte in einer JSP eine Sammlung dieser Bohnen iterieren, jede Person in einem zeigt, HTML-Tabellenzeile, und in der letzten Zeile der Tabelle möchte ich die Summe aller Altersgruppen anzeigen.

Der Code die Tabellenzeilen zu erzeugen, so etwas wie folgt aussehen:

<c:forEach var="person" items="${personList}"> 
    <tr><td>${person.name}<td><td>${person.age}</td></tr> 
</c:forEach> 

Allerdings bin ich kämpfen, um einen Weg zu finden, das Alter insgesamt zu berechnen, die in der letzten Zeile angezeigt wird, ohne Rückgriff Codeschlüsselcode, irgendwelche Vorschläge?

+0

Addieren Sie alle Altersgruppen zusammen und zeigen das in der letzten Zeile an? – ScArcher2

Antwort

36

Hinweis: Ich habe versucht, Antworten kombiniert zu machen eine umfassende Liste. Ich habe Namen erwähnt, wo es angebracht ist, Kredit zu geben, wo es fällig ist.

Es gibt viele Möglichkeiten, um dieses Problem zu lösen, mit Vor/Nachteilen mit jedem verbunden:

reiner JSP-Lösung

Wie ScArcher2 oben erwähnt, eine sehr einfache und einfache Lösung für das Problem ist, es direkt in der JSP zu implementieren, wie so:

<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} 

das Problem bei dieser Lösung ist, dass die JSP zu dem Punkt verwirrend wird, wo Sie auch haben könnten ich Einführung von Scriplets. Wenn Sie erwarten, dass jeder, der auf die Seite schaut, in der Lage ist, der rudimentären Logik zu folgen, ist dies eine gute Wahl.

Reine EL Lösung

Wenn Sie bereits auf EL 3.0 (Java EE 7/Servlet 3.1) verwenden, um neue Unterstützung für streams and 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()} 

JSP EL Funktionen

Eine andere Möglichkeit, die Summe auszugeben, ohne Scriplet-Code in Ihre JSP einzufügen, ist die Verwendung einer EL-Funktion. Mit EL-Funktionen können Sie eine öffentliche statische Methode in einer öffentlichen Klasse aufrufen. Wenn Sie beispielsweise über Ihre Sammlung iterieren und die Werte summieren möchten, können Sie eine öffentliche statische Methode namens sum (List people) in einer öffentlichen Klasse definieren, die möglicherweise als PersonalUtils bezeichnet wird. In Ihrer TLD-Datei würden Sie die folgende Erklärung setzen:

<function> 
    <name>sum</name> 
    <function-class>com.example.PersonUtils</function-class> 
    <function-signature>int sum(java.util.List people)</function-signature> 
</function> 

Innerhalb Ihrer JSP würden Sie schreiben:

<%@ taglib prefix="f" uri="/your-tld-uri"%> 
... 
<c:out value="${f:sum(personList)}"/> 

JSP EL Funktionen einige Vorteile haben. Sie ermöglichen es Ihnen, vorhandene Java-Methoden zu verwenden, ohne dass Sie für eine bestimmte Benutzeroberfläche codieren müssen (Custom Tag Libraries). Sie sind auch kompakt und werden eine nicht programmierorientierte Person nicht verwirren.

Eigener Tag

Eine weitere Option ist Ihren eigenen benutzerdefinierten Tag zu rollen. Diese Option beinhaltet die meisten Einstellungen, aber wird Ihnen geben, was ich denke, dass Sie im Wesentlichen suchen, absolut keine Skriptlets.Ein nettes Tutorial für einfache benutzerdefinierte Tags verwenden, können bei http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701

Die Schritte, die zu finden sind Subklassifizieren 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; 
    } 
} 

das Tag in einer TLD-Datei definieren:

<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> 

die taglib Deklarieren auf Oben auf der JSP:

und verwenden Sie das Tag:

<c:forEach var="person" items="${personList}"> 
    <tr><td>${person.name}<td><td>${person.age}</td></tr> 
</c:forEach> 
<p:personSum personList="${personList}"/> 

Anzeige Tag

Wie zmf bereits erwähnt, können Sie auch das Display-Tag verwenden, obwohl Sie die entsprechenden Bibliotheken umfassen müssen:

http://displaytag.sourceforge.net/11/tut_basic.html

+0

Berechnung Summen in der Steuerung - nicht in der JSP - ist wirklich sehr zu bevorzugen. Verwenden Sie ein MVC-Framework, z. B. Spring, anstatt zu versuchen, in JSP oder JSTL zu viel zu tun. –

0

Es ist ein bisschen hacky, aber in Ihrem Controller-Code könnten Sie einfach ein dummy Person-Objekt mit der Summe darin erstellen!

Wie rufen Sie Ihre Objekte ab? Mit HTML können Sie ein <TFOOT> Element festlegen, das sich am Ende aller vorhandenen Daten befindet. Daher können Sie die Summe unabhängig von den Person-Objekten festlegen und auf der Seite ohne Berechnung auf der JSP-Seite ausgeben.

3

Versuchen Sie, alle Altersgruppen zusammenzufassen?

Sie könnten es in Ihrem Controller berechnen und nur das Ergebnis in der JSP anzeigen.

Sie können ein benutzerdefiniertes Tag für die Berechnung schreiben.

Sie können es in der JSP mit JSTL wie folgt berechnen.

<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} 
1

ScArcher2 hat die einfachste solution. Wenn Sie etwas so kompakt wie möglich wollten, könnten Sie eine Tag-Bibliothek mit einer "Summe" -Funktion darin erstellen. Etwas wie:

class MySum { 
public double sum(List list) {...} 
} 

In Ihrer TLD:

<function> 
<name>sum</name> 
<function-class>my.MySum</function-class> 
<function-signature>double sum(List)</function-signature> 
</function> 

In JSP, würden Sie so etwas wie haben:

<%@ taglib uri="/myfunc" prefix="f" %> 

${f:sum(personList)} 
+0

Nicht vielseitig - welche Eigenschaft oder Funktion result sum() berechnet werden soll, kann nicht angegeben werden. Entweder bist du den langen Weg gegangen, um einen Einzweck-Operator zu machen, oder du musst weiter gehen und dich mit Reflektion hacken, um es vielseitig zu machen. –

+0

Kurze und richtige Antwort: Berechnen Sie die Zusammenfassung im Controller, nicht in JSP. –

0

Sie laufen kann über eine Sammlung mit JSTL gemäß folgenden

<c:forEach items="${numList}" var="item"> 
     ${item} 
</c:forEach> 

wenn es eine Karte ist, dass Sie auf den folgenden

<c:forEach items="${numMap}" var="entry"> 
    ${entry.key},${entry.value}<br/> 
</c:forEach> 
0

Berechnung Summen/oder anderen Zusammenfassungen in der Steuerung tun - nicht in der JSP - ist wirklich stark bevorzugt.

Verwenden Sie Java-Code & einen MVC-Ansatz, z. B. Spring MVC Framework, anstatt zu versuchen, zu viel in JSP oder JSTL zu tun; In diesen Sprachen ist die Berechnung sehr schwach & langsam, und macht Ihre JSP-Seiten viel weniger klar.

Beispiel:

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); 
    } 
} 

Design-Entscheidung weise - überall insgesamt erforderlich ist, könnte möglicherweise im nächsten Monat verlängert werden, um einen Mittelwert zu verlangen, eine mittlere, eine Standardabweichung.

JSTL-Berechnungen & Zusammenfassung halten kaum zusammen, in nur insgesamt. Wollen Sie wirklich weitere Anforderungen für die Zusammenfassung in JSTL erfüllen? Ich glaube, die Antwort ist NEIN - und deshalb ist die richtige Design-Entscheidung, im Controller zu berechnen, als gleichermaßen/einfacher und definitiv plausibler-Anforderungen erweiterbar.

Verwandte Themen