JSTL, pour partir à la chasse des scriplets dans les JSP

January 6th, 2005 par Freddy Mallet

Quand on travaille dans le temps sur des applications web un peu complexes et avec plusieurs contributeurs, il n’est pas rare de voir le contenu des JSP se transformer progressivement en un enchevêtrement informe de scriptlets. Les scriptlets étant ces verrues de bout de code java qui viennent insidieusement se glisser au milieu de votre code HTML et qui ressemble à cela:

< %
  if( toto.getName().equals("Paul")){
   %>
        < %=toto.getName()%> habite la rue < %=toto.getStreet()%>
   < %
           Iterator childrenIterator = toto.getChildren();
           while(childrenIterator .hasNext()){
                Child child = (Child)childrenIterator .next();
	%>
		Un enfant de < %=toto.getName()%> s'appelle < %=child.getName()%>
	< %
	}
}
%>

dès que le mal commence à se répandre, les développeurs ont de moins en moins de scrupules à polluer les JSP avec ces scriplets. Un des moyens de contourner ce problème était purement et simplement d’abandonner les JSP au profit d’autres moteurs de template plus restrictifs comme velocity (le terme structurant serait peut être plus approprié) ou alors de se refaire des taglibs maison (no comment). La venue de JSTL (JavaServer Pages Standard Tag Library) permet de remettre un peu d’ordre dans le monde des JSP. Si nous reprenons l’exemple précédant, en JSTL ça donne le code suivant:

< c:if test="${toto.name eq 'Paul'}">
    <c:out value="${toto.name}"/> habite la rue <c:out value="${toto.street}"/>
     <c:forEach var="child" item="toto.children">
           Un enfant de  <c:out value="${toto.name}"/> s'appelle <c:out value="${child.name}"/>
     </c:forEach>
</c:if>

Au final, on obtient:

- un code humainement plus visible,
- qui peut être plus facilement interprété par des outils d’édition comme dreamweaver
- mais qui surtout ne peut déraper et c’est à mons sens le point le plus important.
En effet si, vous vous imposez de travailler uniquement avec JSTL au sein des JSP, ces dernières ne pourront diverger de leur rôle de vue (au sens MVC). Avec les scriptlets il est décidément trop facile de coder pour ne pas un jour ou l’autre briser même de façon légère le triptyque MVC.

J’en profite également pour vous conseillez de faire un petit tour sur les taglibs jakarta. On trouve par exemple une taglib ‘data grid’ qui prend en charge automatiquement les notions de pagination et de tri de colonnes sur les tableaux.

Liens:
JSTL
taglibs jakarta

2 Responses to “JSTL, pour partir à la chasse des scriplets dans les JSP”

  1. Eric Says:

    C’est ben vrai ça ! C’est le bon sens vendéen.
    Malheureusement même en utilisant JSTL cela n’empêche en rien d’avoir un code qui devient illisible :

    <hrc:forEachEdLibre in="<%=vElement%>" var="edLibreWrapper" action="<%=action%>">
    
                  <c_rt:choose>
                  <c_rt:when test="<%=edLibreWrapper.isInTable()%>">
                        <%if (bTablefirst) {
                            bTablefirst=false;%>
                              <tr>
                                  <td colspan=2>
                                      <table width="100%" cellpadding=0 cellspacing=0 border=0 align=center>
                             <%}%>
                                 <c_rt:choose>
                                        <c_rt:when test="<%=edLibreWrapper.isTitle()%>">
                                                <c_rt:choose>
                                                    <c_rt:when test="<%="1".equalsIgnoreCase(edLibreWrapper.getCoordY())%>">
                                                        <c_rt:choose>
                                                            <c_rt:when test="<%=!("1".equalsIgnoreCase(edLibreWrapper.getCoordX()))%>">
                                                                    </tr>
                                                             </c_rt:when>
                                                                     <tr>
                                                         </c_rt:choose>
                                                    </c_rt:when>
                                                </c_rt:choose>
                                               <th><hrc:edLibreTitle var="edLibreWrapper"/></th>
                                               <c_rt:choose>
                                                    <c_rt:when test="<%=(Integer.toString(nNbLigne).equalsIgnoreCase(edLibreWrapper.getCoordX()) && Integer.toString(nNbColonne).equalsIgnoreCase(edLibreWrapper.getCoordY())) %>">
                                                           </tr>
                                                            <%bTableEnd=true;%>
                                                     </c_rt:when>
                                                 </c_rt:choose>
                                        </c_rt:when>
                                         <c_rt:otherwise>
                                               <c_rt:choose>
                                                    <c_rt:when test="<%="1".equalsIgnoreCase(edLibreWrapper.getCoordY())%>">
                                                        <c_rt:choose>
                                                            <c_rt:when test="<%=!("1".equalsIgnoreCase(edLibreWrapper.getCoordX()))%>">
                                                                        </tr>
                                                             </c_rt:when>
                                                                        <tr>
                                                          </c_rt:choose>
                                                    </c_rt:when>
                                                </c_rt:choose>
                                                 <td align='right'><hrc:edLibreInput var="edLibreWrapper"/></td>
                                                 <c_rt:choose>
                                                    <c_rt:when test="<%=(Integer.toString(nNbLigne).equalsIgnoreCase(edLibreWrapper.getCoordX()) && Integer.toString(nNbColonne).equalsIgnoreCase(edLibreWrapper.getCoordY())) %>">
                                                            </tr>
                                                             <%bTableEnd=true;%>
                                                     </c_rt:when>
                                                 </c_rt:choose>
                                           </c_rt:otherwise>
                                   </c_rt:choose>
                           <%if (bTableEnd) {
                              bTableEnd=false;%>
                              </table>
                              </td>
                            </tr>
                         <%}%>
                   </c_rt:when>
    
                   <c_rt:otherwise>
                               <c_rt:choose>
                                    <c_rt:when test="<%=edLibreWrapper.isTitle()%>">
                                        <tr>
                                            <td colspan=2>
                                                <table class="NOBORDER">
                                                      <tr>
                                                      <c_rt:choose>
                                                        <c_rt:when test="<%= edLibreWrapper.getDefaultValue() != null && edLibreWrapper.getDefaultValue().length() > 0 %>">
                                                            <th class="<%= edLibreWrapper.getDefaultValue() %>"><hrc:edLibreTitle var="edLibreWrapper"/></th>
                                                        </c_rt:when>
                                                        <c_rt:otherwise>
                                                            <th class="title"><hrc:edLibreTitle var="edLibreWrapper"/></th>
                                                        </c_rt:otherwise>
                                                      </c_rt:choose>
                                                      </tr>
                                                </table>
                                               </td>
                                         </tr>
                                     </c_rt:when>
                                     <c_rt:otherwise>
                                            <c_rt:choose>
                                                 <c_rt:when test="<%=edLibreWrapper.isMultiple() && edLibreWrapper.hasDomain()%>">
                                                                <tr>
                                                                    <td colspan="2">
                                                                        <table width="100%" cellpadding=0 cellspacing=0 border=0 align=center>
                                                                            <tr>
                                                                                <td colspan="3"><hrc:edLibreTitle var="edLibreWrapper"/></td>
                                                                            </tr>
                                                                            <tr>
                                                                                <td colspan="3">
                                                                                 <hrc:edLibreInput var="edLibreWrapper" checkboxOuterTable="true"/>
                                                                                </td>
                                                                            </tr>
                                                                        </table>
                                                                    </td>
                                                                </tr>
                                                  </c_rt:when>
                                                  <c_rt:otherwise>
                                                                  <tr>
                                                                    <th> <hrc:edLibreTitle var="edLibreWrapper"/></th>
                                                                    <td>
                                                                         <hrc:edLibreInput var="edLibreWrapper"/>
                                                                    </td>
                                                                </tr>
                                                  </c_rt:otherwise>
                                            </c_rt:choose>
                                      </c_rt:otherwise>
                                 </c_rt:choose>
                      </c_rt:otherwise>
                      </c_rt:choose>
    </hrc:forEachEdLibre>
    

    Je râle, je râle, mais bon c’est quand même mieux car, par respect envers vos yeux délicats, je ne vous montre pas la version scriptlet précédente à l’utilisation de taglib…

    Par hasard aurais-tu jeter un coup d’oeil à JSF ?

    NB. Désolé j’arrive pas à indenter le code…

  2. jbb Says:

    C’est plus de mon age tout ça. Mais bon, je vais vous faire hurler mais cela a un petit air d’ASP (dans le sens code insérer rendant illisible la page) tant critiqué par les développeurs JAVA.
    Bon c’était juste pour vous réveiller un peu !
    Bonne année à tous !

Leave a Reply

You must be logged in to post a comment.