Domanda

Ho un bean Java come questo:

class Person {
  int age;
  String name;
}

Vorrei scorrere su una raccolta di questi bean in un JSP, mostrando ogni persona in una riga della tabella HTML e nell'ultima riga della tabella vorrei mostrare il totale di tutte le età.

Il codice per generare le righe della tabella sarà simile al seguente:

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

Tuttavia, faccio fatica a trovare un modo per calcolare il totale dell'età che verrà mostrato nell'ultima riga senza ricorrere al codice dello scriptlet , qualche suggerimento?

È stato utile?

Soluzione

Nota : Ho provato a combinare le risposte per creare un elenco completo. Ho citato i nomi, se del caso, per dare credito dove è dovuto.

Esistono molti modi per risolvere questo problema, con pro / contro associati a ciascuno:

Soluzione JSP pura

Come ScArcher2 menzionato sopra, una soluzione molto semplice e semplice al problema è implementarlo direttamente nel JSP in questo modo:

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

Il problema con questa soluzione è che JSP diventa confuso al punto in cui potresti aver introdotto anche gli script. Se prevedi che chiunque guardi la pagina sarà in grado di seguire la logica rudimentale presente, questa è una buona scelta.

Soluzione Pure EL

Se sei già su EL 3.0 (Java EE 7 / Servlet 3.1), usa il nuovo supporto per stream e 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()}

Funzioni EL JSP

Un altro modo per produrre il totale senza introdurre il codice di script nel tuo JSP è usare una funzione EL. Le funzioni EL ti consentono di chiamare un metodo statico pubblico in una classe pubblica. Ad esempio, se desideri scorrere la tua raccolta e sommare i valori, puoi definire un metodo statico pubblico chiamato sum (Elenco persone) in una classe pubblica, forse chiamato PersonUtils. Nel tuo file tld dovresti inserire la seguente dichiarazione:

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

All'interno del tuo JSP dovresti scrivere:

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

Le funzioni EL JSP hanno alcuni vantaggi. Consentono di utilizzare metodi Java esistenti senza la necessità di codificare verso un'interfaccia utente specifica (Librerie di tag personalizzate). Sono anche compatti e non confonderanno una persona non orientata alla programmazione.

Tag personalizzato

Ancora un'altra opzione è rotolare il tuo tag personalizzato. Questa opzione coinvolgerà la maggior parte delle impostazioni, ma ti darà quello che penso tu stia cercando in modo essenziale, assolutamente senza scriptlet. Un buon tutorial per l'utilizzo di semplici tag personalizzati è disponibile all'indirizzo http : //java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701

I passaggi coinvolti includono la sottoclasse 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;
   }
}

Definisci il tag in un file 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>

Dichiara i taglib nella parte superiore del tuo JSP:

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

e usa il tag:

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

Visualizza tag

Come menzionato in precedenza zmf, è possibile utilizzare anche il tag display, sebbene sia necessario includere le librerie appropriate:

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

Altri suggerimenti

Stai cercando di sommare tutte le età?

Puoi calcolarlo nel tuo controller e visualizzare solo il risultato in jsp.

Puoi scrivere un tag personalizzato per eseguire il calcolo.

Puoi calcolarlo in jsp usando jstl in questo modo.

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

ScArcher2 ha la soluzione più semplice . Se si desidera qualcosa di più compatto possibile, è possibile creare una libreria di tag con un & Quot; sum & Quot; funzione in esso. Qualcosa del tipo:

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

Nel tuo TLD:

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

Nel tuo JSP, avresti qualcosa del tipo:

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

${f:sum(personList)}

È un po 'confuso, ma nel tuo codice controller potresti semplicemente creare un oggetto Person fittizio con il totale in esso!

Come stai recuperando i tuoi oggetti? L'HTML ti consente di impostare un elemento & Lt; TFOOT & Gt; che siederà in fondo a tutti i dati in tuo possesso, quindi potresti semplicemente impostare il totale separatamente dagli oggetti Person e visualizzarlo sulla pagina così com'è senza alcun calcolo sulla pagina JSP.

puoi iterare su una raccolta usando JSTL come segue

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

se è una mappa che puoi fare sul seguente

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

Il calcolo dei totali / o altri riepiloghi nel controller - non nel JSP - è decisamente preferibile.

Usa il codice Java & amp; un approccio MVC, ad esempio il framework Spring MVC, invece di provare a fare troppo in JSP o JSTL; fare un calcolo significativo in queste lingue è un ampli & debole; lento e rende le pagine JSP molto meno chiare.

Esempio:

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

Progetta dal punto di vista decisionale - dovunque sia richiesto un totale, è possibile che il prossimo mese possa essere esteso per richiedere una media, una mediana, una deviazione standard.

calcoli JSTL & amp; il riassunto non tiene quasi insieme, solo per ottenere un totale. Vuoi davvero soddisfare ulteriori requisiti di riepilogo in JSTL? Credo che la risposta sia NO - e che quindi la decisione progettuale corretta sia quella di calcolare nel Controller, in quanto requisiti ugualmente / più semplici e sicuramente più plausibili estensibili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top