Comment éviter le code Java dans les fichiers JSP?

1673

Je suis nouveau sur Java EE et je sais que quelque chose comme les trois lignes suivantes

<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>

est une méthode de codage à l'ancienne et dans la version 2 de JSP, il existe une méthode pour éviter le code Java dans les fichiers JSP. Quelqu'un peut-il me dire les autres lignes JSP 2 et comment s'appelle cette technique?

chmoelders
la source
22
@Koray Tugay, tant que la variable compteur est déclarée quelque part avant son utilisation, alors elle est très certainement valide ...
Sheldon R.
@SheldonR. Ceci est valide: <% = counter ++%> ou ceci: <%! int compteur = 0; int x = compteur ++; %> mais pas: <%! int compteur = 0; counter ++; %>
Koray Tugay
@KorayTugay, ce que je voulais dire, c'est que si le compteur de variables a été déclaré dans un bloc de script antérieur, il devrait être valide dans un bloc ultérieur. Mais en fin de compte, les programmeurs J2EE devraient de nos jours utiliser des variables EL au lieu de scriptlets, de toute façon ...
Sheldon R.

Réponses:

1972

L'utilisation de scriptlets (ces <% %>choses) dans JSP est en effet fortement déconseillée depuis la naissance des taglibs (comme JSTL ) et EL ( Expression Language , ces ${}choses) en 2001.

Les principaux inconvénients des scriptlets sont:

  1. Réutilisation: vous ne pouvez pas réutiliser des scriptlets.
  2. Remplaçabilité: vous ne pouvez pas rendre les scriptlets abstraits.
  3. OO-capacité: vous ne pouvez pas utiliser l'héritage / composition.
  4. Débogage: si le scriptlet lève une exception à mi-chemin, tout ce que vous obtenez est une page vierge.
  5. Testabilité: les scriptlets ne sont pas testables à l'unité.
  6. Maintenabilité: per saldo, plus de temps est nécessaire pour maintenir la logique du code mélangé / encombré / dupliqué.

Sun Oracle lui-même recommande également dans les conventions de codage JSP d’éviter l’utilisation de scriptlets chaque fois que la même fonctionnalité est possible par les classes (tag). Voici plusieurs citations pertinentes:

A partir de la spécification JSP 1.2, il est fortement recommandé d'utiliser la bibliothèque de balises standard JSP (JSTL) dans votre application Web pour réduire le besoin de scriptlets JSP dans vos pages. Les pages qui utilisent JSTL sont, en général, plus faciles à lire et à gérer.

...

Dans la mesure du possible, évitez les scriptlets JSP chaque fois que les bibliothèques de balises fournissent des fonctionnalités équivalentes. Cela rend les pages plus faciles à lire et à maintenir, aide à séparer la logique métier de la logique de présentation et rendra vos pages plus faciles à évoluer vers des pages de style JSP 2.0 (la spécification JSP 2.0 prend en charge mais met l'accent sur l'utilisation de scriptlets).

...

Dans l'esprit d'adopter le modèle de conception modèle-vue-contrôleur (MVC) pour réduire le couplage entre le niveau de présentation et la logique métier, les scriptlets JSP ne doivent pas être utilisés pour écrire la logique métier. Au lieu de cela, les scriptlets JSP sont utilisés si nécessaire pour transformer les données (également appelées "objets de valeur") renvoyées par le traitement des demandes du client dans un format approprié prêt pour le client. Même alors, cela serait mieux fait avec un servlet de contrôleur frontal ou une balise personnalisée.


La façon de remplacer les scriptlets dépend entièrement du seul objectif du code / de la logique. Le plus souvent, ce code doit être placé dans une classe Java complète:

  • Si vous souhaitez invoquer le même code Java à chaque demande, peu ou pas quelle que soit la page demandée, par exemple en vérifiant si un utilisateur est connecté, puis implémentez un filtre et écrivez le code en conséquence dans la doFilter()méthode. Par exemple:

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
            ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page.
        } else {
            chain.doFilter(request, response); // Logged in, just continue request.
        }
    }

    Lorsqu'il est mappé sur une page appropriée <url-pattern>couvrant les pages JSP d'intérêt, vous n'avez pas besoin de copier-coller le même morceau de code dans l'ensemble des pages JSP.


  • Si vous souhaitez appeler du code Java pour prétraiter une demande, par exemple en préchargeant une liste d'une base de données à afficher dans une table, si nécessaire en fonction de certains paramètres de requête, implémentez un servlet et écrivez le code en conséquence dans la doGet()méthode. Par exemple:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            List<Product> products = productService.list(); // Obtain all products.
            request.setAttribute("products", products); // Store products in request scope.
            request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table.
        } catch (SQLException e) {
            throw new ServletException("Retrieving products failed!", e);
        }
    }

    Cette façon de traiter les exceptions est plus facile. La base de données n'est pas accessible au cours du rendu JSP, mais bien avant que la JSP ne soit affichée. Vous avez toujours la possibilité de modifier la réponse chaque fois que l'accès à la base de données lève une exception. Dans l'exemple ci-dessus, la page d'erreur 500 par défaut sera affichée que vous pouvez de toute façon personnaliser par un <error-page>in web.xml.


  • Si vous souhaitez invoquer du code Java pour post -traiter une demande, par exemple le traitement d'une soumission de formulaire, alors implémentez un servlet et écrivez le code en conséquence dans la doPost()méthode. Par exemple:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);
    
        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            response.sendRedirect("home"); // Redirect to home page.
        } else {
            request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope.
            request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error.
        }
    }

    De cette façon , traiter différentes destinations de la page de résultats est plus facile: réafficher la forme avec des erreurs de validation dans le cas d'une erreur (dans cet exemple particulier , vous pouvez réafficher à l'aide ${message}en EL ), ou tout simplement prendre à la page cible souhaitée en cas de succès.


  • Si vous souhaitez invoquer du code Java pour contrôler le plan d'exécution et / ou la destination de la demande et de la réponse, implémentez un servlet conformément au modèle de contrôleur frontal du MVC . Par exemple:

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Action action = ActionFactory.getAction(request);
            String view = action.execute(request, response);
    
            if (view.equals(request.getPathInfo().substring(1)) {
                request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
            } else {
                response.sendRedirect(view);
            }
        } catch (Exception e) {
            throw new ServletException("Executing action failed.", e);
        }
    }

    Ou adoptez simplement un framework MVC comme JSF , Spring MVC , Wicket , etc. afin de vous retrouver avec juste une page JSP / Facelets et une classe JavaBean sans avoir besoin d'un servlet personnalisé.


  • Si vous souhaitez invoquer du code Java pour contrôler le flux dans une page JSP, vous devez saisir une balise de contrôle de flux (existante) comme le noyau JSTL . Par exemple, afficher List<Product>dans un tableau:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    ...
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td>${product.name}</td>
                <td>${product.description}</td>
                <td>${product.price}</td>
            </tr>
        </c:forEach>
    </table>

    Avec des balises de style XML qui s'intègrent bien dans tout ce HTML, le code est mieux lisible (et donc mieux maintenable) qu'un tas de scriptlets avec diverses accolades d'ouverture et de fermeture ( "Où diable cette accolade de fermeture appartient-elle?" ). Une aide simple consiste à configurer votre application Web pour lever une exception chaque fois que des scriptlets sont toujours utilisés en ajoutant l'élément suivant à web.xml:

    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <scripting-invalid>true</scripting-invalid>
        </jsp-property-group>
    </jsp-config>

    Dans Facelets , le successeur de JSP, qui fait partie du framework MVC JSF fourni par Java EE , il n'est déjà pas possible d'utiliser des scriptlets . De cette façon, vous êtes automatiquement obligé de faire les choses "dans le bon sens".


  • Si vous voulez invoquer du code Java pour accéder et afficher des données "backend" dans une page JSP, vous devez utiliser EL (Expression Language), ces ${}choses-là. Par exemple, réaffichage des valeurs d'entrée soumises:

    <input type="text" name="foo" value="${param.foo}" />

    Le ${param.foo}affiche le résultat de request.getParameter("foo").


  • Si vous souhaitez appeler du code Java utilitaire directement dans la page JSP (généralement des public staticméthodes), vous devez les définir en tant que fonctions EL. Il y a un taglib de fonctions standard dans JSTL, mais vous pouvez également créer facilement des fonctions vous-même . Voici un exemple de l' fn:escapeXmlutilité de JSTL pour empêcher les attaques XSS .

    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
    ...
    <input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />

    Notez que la sensibilité XSS n'est en aucun cas spécifiquement liée à Java / JSP / JSTL / EL / quoi que ce soit, ce problème doit être pris en compte dans chaque application Web que vous développez. Le problème des scriptlets est qu'ils ne fournissent aucun moyen de prévention intégrée, du moins n'utilisant pas l'API Java standard. Le successeur de JSP, Facelets, a déjà un échappement HTML implicite, vous n'avez donc pas à vous soucier des trous XSS dans Facelets.

Voir également:

BalusC
la source
117
+1 Excellente réponse. Mais ne soyez pas dogmatique, parfois utiliser des scriptlets EST ok, mais cela devrait être l'exception qui confirme la règle.
svachon
26
@svachon: les scriptlets sont utiles pour le prototypage / test rapide. Pour autant que je sache, il n'y a qu'une seule utilisation de production "légitime" d'un scriptlet, à savoir <% response.getWriter().flush(); %>entre le </head>et le <body>pour améliorer les performances d'analyse des pages Web dans le navigateur Web. Mais cette utilisation est à son tour complètement négligeable lorsque la taille du tampon de sortie côté serveur est faible (1 ~ 2 Ko). Voir aussi cet article .
BalusC
5
@BalusC Quelques fois, j'ai été coincé avec des classes java qui ne suivaient pas le modèle getter / setter. À mon humble avis, c'est un cas où un scripltet fait le travail.
svachon
41
@svachon: J'envelopperais ces classes avec leurs propres classes javabean et les utiliserais à la place.
BalusC
31
C'était une assez bonne réponse, mais les parties doGet et doPost sont trompeuses. Ces méthodes sont destinées à traiter des méthodes de requête spécifiques (HEAD, GET et POST) et ne sont pas destinées aux requêtes de "prétraitement" ou de "post-traitement"!
MetroidFan2002
225

En tant que sauvegarde: désactivez définitivement les scriptlets

Comme une autre question est en cours de discussion, vous pouvez et devez toujours désactiver les scriptlets dans le web.xmldescripteur de votre application Web.

Je le ferais toujours pour empêcher tout développeur d'ajouter des scriptlets, en particulier dans les grandes entreprises où vous perdrez la vue d'ensemble tôt ou tard. Les web.xmlparamètres ressemblent à ceci:

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
     <scripting-invalid>true</scripting-invalid>
  </jsp-property-group>
</jsp-config>
Stefan Schubert-Peters
la source
4
Est-ce que cela désactive également les commentaires de scriptlet?: <%-- comment that i don't want in the final HTML --%>. Je trouve utile de les utiliser plutôt que des commentaires HTML.
David Lavender
16
@MrSpoon a trouvé une réponse pour vous. Selon cette réponse + commentaire , cela désactive les scriptlets <% %>, les expressions de <%! %>scriptlet et les déclarations de scriptlet <%= %>. Cela signifie que les directives <%@ %>et les commentaires <%-- --%>restent activés et utilisables, vous pouvez donc toujours faire des commentaires et des inclusions.
Martin Carney
3
La désactivation des directives de scriptlet serait terrible - la suppression des espaces blancs est inestimable pour interagir avec les systèmes hérités qui paniquent avec des espaces supplémentaires.
corsiKa
108

JSTL propose des balises pour les conditions, les boucles, les ensembles, les get, etc. Par exemple:

<c:if test="${someAttribute == 'something'}">
   ...
</c:if>

JSTL fonctionne avec les attributs de demande - ils sont le plus souvent définis dans la demande par un servlet, qui les transmet au JSP.

Bozho
la source
2
Pourquoi dites-vous que JSTL fonctionne avec les attributs de demande? Ils peuvent travailler avec des attributs dans n'importe quelle portée, n'est-ce pas?
Koray Tugay
60

Je ne sais pas si j'ai bien compris.

Vous devriez lire quelque chose sur MVC. Spring MVC & Struts 2 sont les deux solutions les plus courantes.

tzim
la source
29
MVC peut être implémenté avec des servlets / jsp en utilisant la plupart des techniques ci-dessus sans Spring ni Struts.
stepanian
18
Comment cela répond à la question?
xyz
54

Vous pouvez utiliser des balises JSTL avec des expressions EL pour éviter de mélanger du code Java et HTML:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
    <head>
    </head>
    <body>

        <c:out value="${x + 1}" />
        <c:out value="${param.name}" />
        // and so on

    </body>
</html>
Behrang Saeedzadeh
la source
34

Il existe également des frameworks basés sur des composants tels que Wicket qui génèrent une grande partie du HTML pour vous. Les balises qui se retrouvent dans le HTML sont extrêmement basiques et il n'y a pratiquement aucune logique qui se mélange. Le résultat est des pages HTML presque vides avec des éléments HTML typiques. L'inconvénient est qu'il y a beaucoup de composants dans l' API Wicket à apprendre et que certaines choses peuvent être difficiles à réaliser sous ces contraintes.

tsand
la source
33

Dans le modèle architectural MVC, les JSP représentent la couche View. L'incorporation de code java dans les JSP est considérée comme une mauvaise pratique. Vous pouvez utiliser JSTL , freeMarker , velocity avec JSP comme "moteur de modèle". Le fournisseur de données de ces balises dépend des cadres avec lesquels vous traitez. Struts 2et webworkcomme une implémentation pour MVC Pattern utilise OGNL "technique très intéressante pour exposer les propriétés Beans à JSP".

Sami Jmii
la source
27

L'expérience a montré que les JSP ont quelques défauts, l'un d'eux étant difficile d'éviter de mélanger le balisage avec le code réel.

Si vous le pouvez, envisagez d'utiliser une technologie spécialisée pour ce que vous devez faire. Dans Java EE 6, il existe JSF 2.0, qui offre de nombreuses fonctionnalités intéressantes, notamment le collage de beans Java avec des pages JSF via l' #{bean.method(argument)}approche.

Thorbjørn Ravn Andersen
la source
3
Ancienne réponse mais je ne résiste pas à dire que JSF est l'une des plus horribles invention de l'espace Java. Essayez de créer un seul lien (comme HTTP GET) et vous comprendrez pourquoi.
Alex
@Alex mais encore mieux. N'hésitez pas à recommander encore mieux.
Thorbjørn Ravn Andersen
26

si vous voulez simplement éviter les inconvénients du codage Java dans JSP, vous pouvez le faire même avec des scriplets. Suivez simplement une certaine discipline pour avoir un minimum de Java dans JSP et presque aucun calcul et logique dans la page JSP.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%//instantiate a JSP controller
MyController clr = new MyController(request, response);

//process action if any
clr.process(request);

//process page forwaring if necessary

//do all variable assignment here
String showMe = clr.getShowMe();%>

<html>
    <head>
    </head>
    <body>
        <form name="frm1">
            <p><%= showMe %>
            <p><% for(String str : clr.listOfStrings()) { %>
            <p><%= str %><% } %>

            // and so on   
        </form>
    </body>
</html>
dipu
la source
26

Apprenez à personnaliser et à écrire vos propres balises à l'aide de JSTL

Notez que EL est EviL (exceptions d'exécution, refactoring) Le
guichet peut également être mauvais (performances, difficile pour les petites applications ou niveau de vue simple)

Exemple de java2s ,

Cela doit être ajouté au web.xml de l'application Web

<taglib>
    <taglib-uri>/java2s</taglib-uri>
    <taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>

créer un fichier: java2s.tld dans le / WEB-INF /

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<!-- a tab library descriptor -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>Java2s Simple Tags</short-name>

    <!-- this tag manipulates its body content by converting it to upper case
    -->
    <tag>
        <name>bodyContentTag</name>
        <tag-class>com.java2s.BodyContentTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
          <name>howMany</name>
        </attribute>
    </tag>
</taglib>

compilez le code suivant dans WEB-INF \ classes \ com \ java2s

package com.java2s;

import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyContentTag extends BodyTagSupport{
    private int iterations, howMany;

    public void setHowMany(int i){
        this.howMany = i;
    }

    public void setBodyContent(BodyContent bc){
        super.setBodyContent(bc);
        System.out.println("BodyContent = '" + bc.getString() + "'");
    }

    public int doAfterBody(){
        try{    
            BodyContent bodyContent = super.getBodyContent();
            String bodyString  = bodyContent.getString();
            JspWriter out = bodyContent.getEnclosingWriter();

            if ( iterations % 2 == 0 ) 
                out.print(bodyString.toLowerCase());
            else
                out.print(bodyString.toUpperCase());

            iterations++;
            bodyContent.clear(); // empty buffer for next evaluation
        }
        catch (IOException e) {
            System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
            e.printStackTrace();
        } // end of catch

        int retValue = SKIP_BODY;

        if ( iterations < howMany ) 
            retValue = EVAL_BODY_AGAIN;

        return retValue;
    }
}

Démarrez le serveur et chargez bodyContent.jsp dans le navigateur

<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
    <head>
        <title>A custom tag: body content</title>
    </head>
    <body>
        This page uses a custom tag manipulates its body content.Here is its output:
        <ol>
            <java2s:bodyContentTag howMany="3">
            <li>java2s.com</li>
            </java2s:bodyContentTag>
        </ol>
    </body>
</html>
tomasb
la source
bien que la réutilisabilité des composants soit bonne, elle cible certains domaines
tomasb
25

Le portillon est également une alternative qui sépare complètement java du html, de sorte qu'un concepteur et un programmeur peuvent travailler ensemble et sur différents ensembles de code sans se comprendre.

Regardez Wicket.

msj121
la source
23

Vous avez posé une bonne question et bien que vous ayez obtenu de bonnes réponses, je vous suggère de vous débarrasser de JSP. C'est une technologie dépassée qui finira par mourir. Utilisez une approche moderne, comme les moteurs de modèles. Vous aurez une séparation très claire des couches métier et de présentation, et certainement pas de code Java dans les modèles, vous pouvez donc générer des modèles directement à partir du logiciel d'édition de présentation Web, dans la plupart des cas en utilisant WYSIWYG.

Et évitez certainement les filtres et le pré et post-traitement, sinon vous risquez de rencontrer des difficultés de support / débogage car vous ne savez toujours pas où la variable obtient la valeur.

Dmitriy R
la source
9
JSP est lui-même un moteur de template
WarFox
1
-1 - Il existe de nombreuses raisons tout à fait valables d'utiliser des filtres, des pré-processeurs et des post-processeurs. Oui, vous pouvez vous retrouver avec des valeurs qui semblent mystérieuses, mais pas si vous comprenez votre architecture.
RustyTheBoyRobot
21

afin d'éviter le code java dans les fichiers JSP java fournit maintenant des bibliothèques de balises comme JSTL également java a mis au point avec JSF dans lequel vous pouvez écrire toutes les structures de programmation sous forme de balises

mahesh
la source
21

Peu importe combien vous essayez d'éviter, lorsque vous travaillez avec d'autres développeurs, certains d'entre eux préfèrent toujours le scriptlet, puis insèrent le code malveillant dans le projet. Par conséquent, la configuration du projet au premier signe est très importante si vous voulez vraiment réduire le code du scriptlet. Il existe plusieurs techniques pour surmonter cela (y compris plusieurs cadres que d'autres ont mentionnés). Cependant, si vous préférez la méthode JSP pure, utilisez le fichier de balises JSTL. La bonne chose à ce sujet est que vous pouvez également configurer des pages maîtres pour votre projet, afin que les autres pages puissent hériter des pages maîtres

Créez une page maître appelée base.tag sous vos balises WEB-INF / avec le contenu suivant

<%@tag description="Overall Page template" pageEncoding="UTF-8"%>

<%@attribute name="title" fragment="true" %>

<html>
  <head>
    <title>  
       <jsp:invoke fragment="title"></jsp:invoke>
    </title>

  </head>
  <body>
    <div id="page-header">
       ....
    </div>
    <div id="page-body">
      <jsp:doBody/>
    </div>
    <div id="page-footer">
      .....
    </div>
  </body>
</html>

Sur cette page mère, j'ai créé un fragment appelé "titre", de sorte que dans la page enfant, je puisse insérer plus de codes à cet endroit de la page maître. De plus, la balise <jsp:doBody/>sera remplacée par le contenu de la page enfant

Créez une page enfant (child.jsp) dans votre dossier WebContent:

<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:base>
    <jsp:attribute name="title"> 
        <bean:message key="hello.world" />
    </jsp:attribute>

    <jsp:body>
    [Put your content of the child here]
    </jsp:body>   
</t:base>

<t:base>est utilisé pour spécifier la page maître que vous souhaitez utiliser (qui est en ce moment base.tag). Tout le contenu à l'intérieur de la balise <jsp:body>remplacera le <jsp:doBody/>sur votre page maître. Votre page enfant peut également inclure n'importe quelle balise lib et vous pouvez l'utiliser normalement comme l'autre mentionnée. Cependant, si vous utilisez du code de scriptlet ici ( <%= request.getParameter("name") %>...) et essayez d'exécuter cette page, vous obtiendrez un JasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here. Par conséquent, il n'y a aucun moyen que d'autres personnes puissent inclure le mauvais code dans le fichier jsp

Appel de cette page depuis votre contrôleur:

Vous pouvez facilement appeler le fichier child.jsp depuis votre contrôleur. Cela fonctionne également bien avec le cadre Struts

Thai Tran
la source
"Peu importe ce que vous essayez d'éviter, lorsque vous travaillez avec d'autres développeurs, certains d'entre eux préfèrent toujours le scriptlet, puis insèrent le code malveillant dans le projet." Voir la réponse «En tant que sauvegarde: désactiver les scriptlets pour de bon».
Lluis Martinez
19

Utilisez JSTL Tag librariesdans JSP, cela fonctionnera parfaitement.

Chandra Sekhar
la source
18

Utilisez simplement la balise JSTL et l'expression EL.

tanglei
la source
17

Si quelqu'un est vraiment contre la programmation dans plusieurs langues , je suggère GWT, théoriquement, vous pouvez éviter tous les éléments JS et HTML, car Google Toolkit transforme tout le client et le code partagé en JS, vous n'aurez aucun problème avec eux, donc vous disposez d'un service Web sans codage dans d'autres langues. Même vous pouvez utiliser du CSS par défaut quelque part car il est fourni par des extensions (smartGWT ou Vaadin). Vous n'avez pas besoin d'apprendre des dizaines d'annotations.

Bien sûr, si vous le souhaitez, vous pouvez vous pirater dans les profondeurs du code et injecter JS et enrichir votre page HTML, mais vous pouvez vraiment l'éviter si vous le souhaitez, et le résultat sera bon car il a été écrit dans d'autres cadres. Je dis que ça vaut le coup d'essayer, et le GWT de base est bien documenté.

Et bien sûr, de nombreux autres programmeurs ont décrit ou recommandé plusieurs autres solutions. GWT est destiné aux personnes qui ne veulent vraiment pas traiter le composant WebPart ou le minimiser.

CsBalazsHungary
la source
1
Ne répond pas vraiment à la question du PO.
Evan Donovan
1
@EvanDonovan bien, pratiquement il donne une réponse. Vous n'avez pas besoin de jouer avec les codes Java mélangés avec d'autres langages. J'admets qu'il utilise Java pour le codage, mais il sera traduit en JS sans appels Java. Mais la portée de la question est de savoir comment éviter le chaos de la JSP classique. Et la technologie GWT résout cela. J'ai ajouté cette réponse car personne ne l'a mentionnée, mais pertinente car c'est une alternative à JSP. Je ne voulais pas répondre à l'ensemble de la question, mais ajouter une information précieuse pour les personnes qui recherchent des alternatives.
CsBalazsHungary
16

Une bonne idée du monde Python sont langages d'attribut Template ; TAL a été introduit par Zope (donc alias "Zope Page Templates", ZPT) et est un standard, avec des implémentations en PHP, XSLT et Java également (j'ai utilisé les incarnations Python / Zope et PHP). Dans cette classe de langages de modèles, un exemple ci-dessus pourrait ressembler à ceci:

<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name">Example product</td>
        <td tal:content="product/description">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

Le code ressemble à du HTML ordinaire (ou XHTML) plus quelques attributs spéciaux dans un espace de noms XML; il peut être visualisé avec un navigateur et être modifié en toute sécurité par un designer. Les macros et i18n sont également pris en charge:

<h1 i18n:translate="">Our special offers</h1>
<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name"
            i18n:translate="">Example product</td>
        <td tal:content="product/description"
            i18n:translate="">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

Si des traductions du contenu sont disponibles, elles sont utilisées.

Cependant, je ne connais pas grand-chose à l' implémentation Java .

Tobias
la source
1
Depuis décembre 2009, JSP a été remplacé par Facelets qui prend en charge ce genre de choses. Facelets est également basé sur XML. Voir aussi entre autres le chapitre Facelets dans Java EE 6 et les ui:xxxbalises dans Facelts VDL .
BalusC
Je ne connais pas très bien Facelets, mais IIRC est tout au sujet de l'écriture de classes qui implémentent des éléments XML personnalisés. La manière TAL / ZPT est d'avoir des modèles qui contiennent du vrai (X) HTML avec des attributs spéciaux qui remplissent ou remplacent les éléments originaux; ainsi, vous pouvez afficher le modèle de travail et voir un prototype avec un joli contenu factice. Je ne suis pas sûr que les Facelets permettent de modifier les éléments HTML d'origine (sans espace de noms supplémentaire) à l'aide d'attributs personnalisés.
Tobias
Je viens de jeter un coup d'œil à ce truc des Facelets. Il contient toutes sortes d'installations de validation, etc. et suit donc une philosophie complètement différente de TAL. La manière TAL est la suivante: «Gardez la logique hors du modèle aussi proprement que possible; faites tout le travail compliqué par le contrôleur qui l'alimente. Vous ne donnerez jamais un modèle Facelets à un designer pour le faire peaufiner; ce n'est tout simplement pas possible. En ce qui concerne le contenu généré - c'est comme utiliser des tal:replace="structure (expression)"attributs tout le temps.
Tobias
14

Bien sûr, remplacez <%! counter++; %> par une architecture producteur-consommateur d'événements, où la couche métier est informée de la nécessité d'incrémenter le compteur, elle réagit en conséquence et avertit les présentateurs afin qu'ils mettent à jour les vues. Un certain nombre de transactions de base de données sont impliquées, car à l'avenir, nous devrons connaître la valeur nouvelle et ancienne du compteur, qui l'a incrémenté et dans quel but. De toute évidence, la sérialisation est impliquée, car les couches sont entièrement découplées. Vous pourrez incrémenter votre compteur sur RMI, IIOP, SOAP. Mais seul le HTML est requis, ce que vous n'implémentez pas, car c'est un cas banal. Votre nouvel objectif est d'atteindre 250 incréments par seconde sur votre nouveau brillant serveur E7, 64 Go de RAM.

J'ai plus de 20 ans en programmation, la plupart des projets échouent avant le sextet: Réutilisabilité Remplaçabilité OO-capacité Débogage Testabilité La maintenabilité est même nécessaire. D'autres projets, dirigés par des gens qui ne se soucient que de la fonctionnalité, ont connu un succès retentissant. De plus, une structure d'objet rigide, implémentée trop tôt dans le projet, rend le code incapable d'être adapté aux changements drastiques des spécifications (aka agile).

Je considère donc comme une procrastination l'activité de définition de "couches" ou de structures de données redondantes soit au début du projet, soit lorsque cela n'est pas spécifiquement requis.  

Razvan
la source
11

Techniquement, les JSP sont tous convertis en Servlets pendant l'exécution . JSP a été initialement créé dans le but de découpler la logique métier et la logique de conception, en suivant le modèle MVC. Donc JSP sont techniquement tous les codes java pendant l'exécution. Mais pour répondre à la question, les bibliothèques de balises sont généralement utilisées pour appliquer la logique (supprimer les codes Java) aux pages JSP.

mel3kings
la source
8

Si nous utilisons les éléments suivants dans une application Web Java, le code Java peut être éliminé du premier plan de la JSP.

  1. Utiliser l'architecture MVC pour l'application Web

  2. Utiliser des balises JSP

    une. Balises standard

    b. Balises personnalisées

  3. Langage d'expression

Ajay Takur
la source
8

Comment éviter le code Java dans les fichiers JSP?

Vous pouvez utiliser des balises de bibliothèque d'onglets comme JSTL en plus du langage d'expression ( EL ). Mais EL ne fonctionne pas bien avec JSP. Il est donc préférable de supprimer complètement JSP et d'utiliser Facelets .

Facelets est le premier langage de déclaration de page non JSP conçu pour JSF (Java Server Faces) qui a fourni un modèle de programmation plus simple et plus puissant aux développeurs JSF par rapport à JSP. Il résout différents problèmes survenant dans JSP pour le développement d'applications Web.

entrez la description de l'image ici

La source

Yster
la source
J'appuie définitivement cette réponse. JSF avec ou sans facettes. Je pensais que le développement dans JSP avait largement cessé il y a plus de 10 ans. J'ai écrit pour la dernière fois des JSP en 2000!
bagages
4

L'utilisation de Scriptlets est une méthode très ancienne et non recommandée. Si vous voulez sortir directement quelque chose dans vos pages JSP, utilisez simplement Expression Language (EL) avec JSTL .

Il existe également d'autres options telles que l'utilisation d'un moteur de modélisation comme Velocity, Freemarker, Thymeleaf etc.

Notez également qu'il n'est pas recommandé de faire de la logique métier dans la couche de vue, vous devez effectuer vos logiques métier dans la couche Service et transmettre le résultat de la sortie à vos vues via un contrôleur.

adn.911
la source
3

Rien de tout cela n'est utilisé mon ami, mon conseil est de découpler la vue (css, html, javascript, etc.) du serveur.

Dans mon cas, je fais mes systèmes en gérant la vue avec Angular et toutes les données nécessaires sont importées du serveur à l'aide des services de repos.

Croyez-moi, cela va changer la façon dont vous concevez

Eduardo
la source
3

Utilisez le backbone, angulaire comme le framework javascript pour la conception de l'interface utilisateur et récupérez les données à l'aide de l'api de repos. Cela supprimera complètement la dépendance java de l'interface utilisateur.

Sumesh TG
la source
3

JSP 2.0 a une fonctionnalité appelée "Tag Files" , vous pouvez écrire des balises sans javacode externe et tld. Vous devez créer un .tagfichier et le mettre, WEB-INF\tagsvous pouvez même créer une structure de répertoire pour empaqueter vos balises.

Par exemple:

/WEB-INF/tags/html/label.tag

<%@tag description="Rensders a label with required css class" pageEncoding="UTF-8"%>
<%@attribute name="name" required="true" description="The label"%>

<label class="control-label control-default"  id="${name}Label">${name}</label>

Utilisez-le comme

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/html"%>
<h:label  name="customer name" />

En outre, vous pouvez facilement lire le corps de la balise

/WEB-INF/tags/html/bold.tag
<%@tag description="Bold tag" pageEncoding="UTF-8"%>
<b>
  <jsp:doBody/>
</b>

Utilise le

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/bold"%>
<h:bold>Make me bold</h:bold>

Les exemples sont très simples mais vous pouvez effectuer de nombreuses tâches compliquées ici. S'il vous plaît considérez que vous pouvez utiliser d' autres balises (par exemple: JSTLqui a le contrôle des balises comme la if/forEcah/chosenmanipulation de texte comme format/contains/uppercaseou même les balises SQL select/update), passer tous les paramètres nature, par exemple Hashmap, l' accès session, request... dans votre fichier d'étiquette aussi.

Les fichiers de balises sont si faciles à développer que vous n'avez pas eu besoin de redémarrer le serveur lors de leur modification, comme les fichiers JSP. Cela les rend faciles à développer.

Même si vous utilisez un framework comme Struts 2, qui a beaucoup de bonnes balises, vous pouvez constater que le fait d'avoir vos propres balises peut réduire considérablement votre code. Vous pouvez passer vos paramètres de balise à struts et personnaliser ainsi votre balise de framework.

Vous pouvez utiliser la balise non seulement pour éviter Java, mais aussi pour minimiser vos codes HTML. J'essaie moi-même de revoir les codes HTML et de créer beaucoup de balises dès que les doublons de code commencent dans mes pages.

(Même si vous finissez par utiliser le java dans votre code JSP, ce que j'espère que non, vous pouvez encapsuler ce code dans une balise)

Alireza Fattahi
la source
1

Comme le disent de nombreuses réponses, utilisez JSTL ou créez vos propres balises personnalisées. Voici une bonne explication sur la création de balises personnalisées

Code_Mode
la source
1
  1. Faites vos valeurs et paramètres dans vos classes de servlet
  2. Récupérez ces valeurs et paramètres dans votre JSP à l'aide de JSTL / Taglib

La bonne chose à propos de cette approche est que votre code est aussi du code HTML!

Mehdi
la source
0

En utilisant des balises JSTL avec une expression EL, vous pouvez éviter cela. Mettez les choses suivantes dans votre page jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
bhanwar rathore
la source