1752 votes

Comment éviter de Code Java dans les pages JSP-Files?

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

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

est un oldschool façon de coder et JSP version 2, il existe une méthode pour éviter de code Java dans les pages JSP. Quelqu'un peut-il me dire l'alternative JSP 2 lignes, et comment cette technique est appelée?

2019voto

BalusC Points 498232

L'utilisation de scriptlets (ceux - <% %> choses) JSP est en effet fortement déconseillé depuis la naissance de taglibs (comme JSTL) et EL (Expression Language, ceux - ${} choses) il y a une décennie. Les inconvénients majeurs de scriptlets sont:

  1. Réutilisabilité: vous ne pouvez pas réutiliser les scriptlets.
  2. Remplacement: vous ne pouvez pas faire les scriptlets abstrait.
  3. OO-capacité: vous ne pouvez pas faire usage de l'héritage et de composition.
  4. Debuggability: si scriptlet déclenche une exception à mi-chemin, tout ce que vous obtenez est une page vierge.
  5. La testabilité: les scriptlets ne sont pas de l'unité-testable.
  6. Maintenabilité: per saldo plus de temps est nécessaire pour maintenir la mêlée/encombré/code dupliqué logique.

Sun Oracle lui-même recommande également dans la JSP conventions de codage pour éviter l'utilisation de scriptlets chaque fois que la même fonctionnalité est possible par (tag) des classes. Voici plusieurs cites de pertinence:

De JSP 1.2 de la Spécification, il est fortement recommandé que le JSP Standard Tag Library (JSTL) être utilisé dans votre application web pour aider à réduire la nécessité pour les JSP les scriptlets dans vos pages. Les Pages qui utilisent JSTL sont, en général, plus facile à lire et à maintenir.

...

Si possible, éviter les JSP les scriptlets chaque fois que les bibliothèques de balises fournissent des fonctionnalités équivalentes. Cela rend les pages plus facile à lire et à maintenir, permet de séparer la logique métier de la présentation de la logique, et de rendre vos pages plus facile d'évoluer dans JSP 2.0 de style pages (JSP 2.0 prend en charge, mais savoir l'utilisation de scriptlets).

...

Dans l'esprit de l'adoption du modèle-vue-contrôleur (MVC) modèle de conception pour réduire le couplage entre la couche de présentation de la logique d'entreprise, JSP scriptlets ne doit pas être utilisé pour l'écriture de la logique. Plutôt, JSP scriptlets sont utilisés si nécessaire pour transformer les données (également appelé "objets de valeur") revient de traiter les demandes des clients dans le dans un bon client format prêt. Même alors, ce serait mieux fait avec un contrôleur frontal servlet ou une balise personnalisée.

Comment remplacer les scriptlets dépend entièrement de l'unique but de le code/la logique. Plus souvent, ce code doit être placé dans un fullworthy classe Java.

  • Si vous voulez invoquer le même code Java sur chaque demande, moins ou plus, indépendamment de la page demandée, par exemple, de vérifier si un utilisateur est connecté, puis de mettre en œuvre un filtre et d'écrire un code en conséquence doFilter() méthode. E. g.:

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

    Lorsque mappé sur l' <url-pattern> couvrant les pages JSP de l'intérêt, vous n'avez pas besoin de copypaste le même morceau de code sur toutes les pages JSP.


  • Si vous voulez vous prévaloir de certains de code Java pour traiter une demande, par exemple, le préchargement de certains liste à partir d'une base de données à afficher dans un tableau, si nécessaire sur la base de certains paramètres de la requête, puis de mettre en œuvre une servlet et écrire du code en conséquence doGet() méthode. E. g.:

    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 des exceptions est plus facile. La DB n'est pas accessible dans le milieu de la page JSP, le rendu, mais de bien avant la JSP est affiché. Vous avez toujours la possibilité de modifier la réponse à chaque fois que la DB accès déclenche une exception. Dans l'exemple ci-dessus, l'erreur par défaut de 500 page s'affiche qui vous pouvez de toute façon personnaliser par un <error-page> en web.xml.


  • Si vous voulez vous prévaloir de certains de code Java pour post-traiter une demande, par exemple, le traitement de la soumission d'un formulaire, puis de mettre en œuvre une servlet et écrire du code en conséquence doPost() méthode. E. g.:

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

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


  • Si vous voulez vous prévaloir de certains de code Java pour contrôler le plan d'exécution et/ou de la destination de la demande et la réponse, puis de mettre en œuvre une servlet selon la MVC du Modèle de Contrôleur Frontal. E. g.:

    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 tout simplement adopter un framework MVC comme JSF, Spring MVC, Wicket, etc, de sorte que vous vous retrouvez avec seulement une JSP/Facelets page et une classe Javabean sans avoir besoin d'un custom servlet.


  • Si vous voulez vous prévaloir de certains de code Java pour contrôler le flux à l'intérieur d'une page JSP, alors vous avez besoin de saisir un (existant) de contrôle de débit taglib comme JSTL de base. E. g. affichage 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 XML, les balises de style qui s'intègre parfaitement entre tout ce que le HTML, le code est mieux lisible (et donc plus facile à gérer) que d'un tas de scriptlets avec divers d'ouverture et de fermeture des accolades ("Où diable est-ce à l'accolade de fermeture appartient-il?"). Une simple aide à configurer votre application web pour lancer une exception lorsque les scriptlets sont encore utilisés par adjonction de la partie suivante de 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 de la Java EE fourni MVC framework JSF, c'est déjà pas possible d'utiliser les scriptlets. De cette façon, vous êtes automatiquement forcé à faire des choses "le droit chemin".


  • Si vous voulez vous prévaloir de certains de code Java pour l'accès et l'affichage "backend" données à l'intérieur d'une page JSP, alors vous devez utiliser l'EL (Expression Language), ceux - ${} choses. E. g. l'affichage des présenté des valeurs de saisie:

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

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


  • Si vous voulez vous prévaloir de certaines utilitaire Java code directement dans la page JSP (typiquement public static méthodes), alors vous avez besoin de les définir comme EL fonctions. Il y a un standard de fonctions taglib dans JSTL, mais vous pouvez aussi facilement créer des fonctions vous-même. Voici un exemple sur la façon de JSTL fn:escapeXml est utile pour éviter les attaques de type XSS attaques.

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

    Notez que le XSS la sensibilité n'a rien de spécifiquement liés à Java/JSP/JSTL/EL/que ce soit, ce problème doit être pris en compte dans tous les webapplication vous développer. Le problème de scriptlets , c'est qu'il ne fournit aucun moyen de builtin préventions, au moins pas à l'aide de la norme API Java. JSP successeur de Facelets a déjà implicite HTML échapper, de sorte que vous n'avez pas besoin de vous soucier de XSS des trous dans les Facelets.

Voir aussi:

230voto

pvblivs Points 2785

Comme une Sauvegarde: Désactiver les Scriptlets Pour de Bon

Aussi une autre question est de discuter, vous pouvez et devriez toujours désactiver les scriptlets dans votre web.xml web descripteur de l'application.

Je serais toujours le faire afin d'éviter tout développeur ajout de scriptlets, en particulier dans les grandes entreprises où vous perdez de vue d'ensemble, tôt ou tard. L' web.xml paramètres ressembler à ceci:

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

110voto

Bozho Points 273663

JSTL propose des balises pour des instructions conditionnelles, boucles, les décors, les gets, etc. Par exemple:

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

JSTL travaille avec les attributs de la requête - ils sont le plus souvent en la demande par une Servlet, qui les transmet à la JSP.

60voto

tzim Points 889

Je ne suis pas sûr si je réussis à corriger.

Vous devriez lire quelque chose à propos de la MVC. Spring MVC & Struts 2 sont les deux plus courants.

55voto

Behrang Points 13471

Vous pouvez utiliser les balises JSTL avec EL expressions à éviter le brassage 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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X