Frage

Ich habe eine Java-Bean wie diese:

class Person {
  int age;
  String name;
}

Ich möchte eine Sammlung dieser Beans in einer JSP durchlaufen und jede Person in einer HTML-Tabellenzeile anzeigen. In der letzten Zeile der Tabelle möchte ich die Gesamtzahl aller Altersgruppen anzeigen.

Der Code zum Generieren der Tabellenzeilen sieht etwa so aus:

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

Ich habe jedoch Schwierigkeiten, eine Möglichkeit zu finden, die Gesamtalterszahl zu berechnen, die in der letzten Zeile angezeigt wird ohne auf Scriptlet-Code zurückzugreifen, irgendwelche Vorschläge?

War es hilfreich?

Lösung

Hinweis: Ich habe versucht, Antworten kombiniert eine umfassende Liste zu machen. Ich erwähnte Namen gegebenenfalls Kredit zu geben, wo sie fällig ist.

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

reine JSP-Lösung

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

<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 man so gut eingeführt scriplets haben könnte. Wenn Sie erwarten, dass auf der Seite sucht jeder in der Lage sein wird, die rudimentäre Logik präsentiert es ist eine gute Wahl zu folgen.

Reiner EL Lösung

Wenn Sie bereits auf EL 3.0 (Java EE 7 / Servlet 3.1) verwenden, um neue Unterstützung für Ströme und Lambda-Ausdrücke :

<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 weitere Möglichkeit zur Ausgabe ohne die Gesamt scriplet Code in Ihre JSP Einführung ist eine EL-Funktion zu verwenden. EL-Funktionen können Sie eine öffentliche statische Methode in einer öffentlichen Klasse nennen. Zum Beispiel wäre, wenn Sie Ihre Sammlung iterieren und die Werte summieren Sie eine öffentliche statische Methode namens sum (Liste der Personen) in einer öffentlichen Klasse definieren könnte, vielleicht PersonUtils genannt. In Ihrer TLD-Datei würde legen Sie die folgende Erklärung:

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

In Ihrer JSP würden Sie schreiben:

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

JSP EL Funktionen haben einige Vorteile. Sie ermöglichen es, ohne die Notwendigkeit, vorhandene Java-Methoden zu verwenden, um eine bestimmte UI (Custom Tag Libraries) zu kodieren. Sie sind auch kompakt und werden keine nicht-Programmierung orientierte Person verwechselt werden.

Benutzerdefinierte Tag

Eine weitere Option ist Ihren eigenen benutzerdefinierten Tag zu rollen. Diese Option wird die meisten Setup beinhalten aber werden Sie geben, was ich denke, Sie esentially suchen, absolut keine Scriptlets. Ein nettes Tutorial für die Verwendung von einfachen benutzerdefinierten Tags können unter http finden : //java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701

Die beteiligten Schritte umfassen 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;
   }
}

Definieren Sie den Tag in einer TLD-Datei:

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

Deklarieren Sie die taglib auf der Oberseite Ihrer JSP:

<%@ taglib uri="/you-taglib-uri" prefix="p" %>

und verwenden Sie den Tag:

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

Display-Tag

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

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

Andere Tipps

Versuchen Sie, alle Altersgruppen zu addieren?

Sie können es in Ihrem Controller berechnen und nur in der jsp das Ergebnis angezeigt werden soll.

Sie können einen benutzerdefinierten Tag schreiben die Berechnung zu tun.

Sie können es in der jsp berechnen jstl wie folgt aus.

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

Überprüfen Sie heraus Display-Tag. http://displaytag.sourceforge.net/11/tut_basic.html

ScArcher2 hat die einfachste Lösung . Wenn man etwas so kompakt wie möglich will, könnten Sie eine Tag-Bibliothek mit einer „Summe“ Funktion darin erstellen. So 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 der JSP, würden Sie so etwas wie haben:

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

${f:sum(personList)}

Es ist ein bisschen hacky, aber in Ihrem Controller-Code können Sie nur ein Dummy-Person-Objekt mit dem gesamten darin erstellt!

Wie abrufen Sie Ihre Objekte? HTML können Sie einstellen, ein Element, das am unteren Ende jeder Daten sitzen Sie haben also könnten Sie einfach separat die Gesamt gesetzt von den Person-Objekten und gibt es auf der Seite ohne Berechnung auf der JSP-Seite als Service-Leistung.

Sie können eine Sammlung mit JSTL nach folgenden iterieren

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

, wenn es sich um eine Karte, die Sie auf das tun können folgende

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

Die Berechnung von Gesamtsummen oder anderen Zusammenfassungen im Controller – nicht im JSP – ist wirklich vorzuziehen.

Verwenden Sie Java-Code und einen MVC-Ansatz, z. B. das Spring MVC-Framework, anstatt zu versuchen, zu viel in JSP oder JSTL zu tun;Umfangreiche Berechnungen in diesen Sprachen sind schwach und langsam und machen 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);
    }
}

Was die Designentscheidung angeht – überall dort, wo eine Gesamtsumme erforderlich ist, könnte im nächsten Monat möglicherweise darauf ausgeweitet werden, dass ein Durchschnitt, ein Median und eine Standardabweichung erforderlich sind.

JSTL-Berechnungen und -Zusammenfassungen halten kaum zusammen, sondern ergeben lediglich eine Gesamtsumme.Wollen Sie wirklich weitere Zusammenfassungsanforderungen in JSTL erfüllen?Ich glaube, die Antwort lautet NEIN – und dass daher die richtige Entwurfsentscheidung darin besteht, im Controller zu rechnen, da die Anforderungen gleichermaßen/einfacher und auf jeden Fall plausibler erweiterbar sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top