Question

J'ai un haricot Java comme celui-ci:

class Person {
  int age;
  String name;
}

Je voudrais parcourir une collection de ces haricots dans un fichier JSP, en montrant chaque personne dans une ligne de tableau HTML, et dans la dernière ligne du tableau, j'aimerais afficher le total de tous les âges.

Le code pour générer les lignes de la table ressemblera à ceci:

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

Toutefois, je ne parviens pas à trouver le moyen de calculer l'âge total qui apparaîtra dans la dernière ligne sans recourir au code de script, , des suggestions?

Était-ce utile?

La solution

Remarque: J'ai essayé de combiner des réponses pour en faire une liste complète. J'ai mentionné des noms, le cas échéant, pour attribuer un crédit le cas échéant.

Il existe de nombreuses façons de résoudre ce problème, avec des avantages / inconvénients associés à chacun:

Solution Pure JSP

Comme ScArcher2 l'a mentionné ci-dessus, une solution très simple et simple consiste à l'implémenter directement dans le JSP, comme suit:

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

Le problème avec cette solution est que le JSP est source de confusion au point que vous auriez aussi bien pu introduire des scriplets. Si vous pensez que tous ceux qui consultent la page pourront suivre la logique rudimentaire, c'est un choix judicieux.

Solution Pure EL

Si vous utilisez déjà EL 3.0 (Java EE 7 / Servlet 3.1), utilisez le nouveau support pour flux et 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()}

Fonctions JSP EL

Une autre façon de générer le total sans introduire de code de scriplet dans votre JSP consiste à utiliser une fonction EL. Les fonctions EL vous permettent d'appeler une méthode statique publique dans une classe publique. Par exemple, si vous souhaitez parcourir votre collection et additionner les valeurs, vous pouvez définir une méthode publique statique appelée sum (List people) dans une classe publique, éventuellement appelée PersonUtils. Dans votre fichier tld, placez la déclaration suivante:

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

Dans votre JSP, vous écririez:

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

Les fonctions JSP EL présentent quelques avantages. Ils vous permettent d'utiliser des méthodes Java existantes sans avoir à coder pour une interface utilisateur spécifique (bibliothèques de balises personnalisées). Ils sont également compacts et ne vont pas confondre une personne non orientée programmation.

Balise personnalisée

Encore une autre option consiste à faire défiler votre propre tag personnalisé. Cette option impliquera le plus d’installation mais vous donnera ce que je pense que vous recherchez essentiellement, absolument pas de scriptlets. Vous trouverez un didacticiel intéressant sur l'utilisation de balises personnalisées simples à l'adresse http. : //java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701

Les étapes impliquées incluent la sous-classe 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;
   }
}

Définissez la balise dans un fichier 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>

Déclarez la balise au sommet de votre JSP:

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

et utilisez la balise:

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

Balise d'affichage

Comme mentionné par zmf plus tôt, vous pouvez également utiliser la balise display, bien que vous deviez inclure les bibliothèques appropriées:

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

Autres conseils

Essayez-vous d’additionner tous les âges?

Vous pouvez le calculer dans votre contrôleur et afficher uniquement le résultat dans le jsp.

Vous pouvez écrire une balise personnalisée pour effectuer le calcul.

Vous pouvez le calculer dans le JSP en utilisant jstl comme ceci.

<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 propose la solution la plus simple. Si vous voulez quelque chose d'aussi compact que possible, vous pouvez créer une bibliothèque de balises avec une & "Somme &"; fonctionner en elle. Quelque chose comme:

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

Dans votre TLD:

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

Dans votre JSP, vous auriez quelque chose comme:

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

${f:sum(personList)}

C'est un peu compliqué, mais dans votre code de contrôleur, vous pouvez simplement créer un objet Personne factice avec le total qu'il contient!

Comment récupérez-vous vos objets? Le langage HTML vous permet de définir un élément & Lt; TFOOT & Gt; qui sera placé au bas de toutes les données que vous avez. Vous pouvez donc définir le total séparément des objets Personne et l’afficher sur la page tel quel, sans aucun calcul sur la page JSP.

vous pouvez parcourir une collection à l'aide de JSTL en fonction de ce qui suit

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

s'il s'agit d'une carte, vous pouvez effectuer les opérations suivantes

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

Le calcul des totaux / ou d'autres résumés dans le contrôleur - et non dans le JSP - est vraiment fortement préférable.

Utiliser le code Java & amp; une approche MVC, par exemple un framework Spring MVC, au lieu d’essayer de faire trop dans JSP ou JSTL; faire des calculs significatifs dans ces langues est faible & amp; lent et rend vos pages JSP beaucoup moins claires.

Exemple:

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

En ce qui concerne la conception, chaque décision est nécessaire: vous pouvez éventuellement prolonger le total le mois prochain de manière à permettre une moyenne, une médiane, un écart-type.

calculs JSTL & amp; les résumés résistent à peine, ils ne font qu’un total. Allez-vous vraiment vouloir répondre à d’autres exigences de synthèse dans JSTL? Je crois que la réponse est NON - et que, par conséquent, la décision de conception correcte est de calculer dans le contrôleur, comme étant également / plus simples et nettement plus plausibles des exigences extensibles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top