¿Cómo evitar el código Java en archivos JSP?


1673

Soy nuevo en Java EE y sé que algo así como las siguientes tres líneas

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

es una forma de codificación de la vieja escuela y en JSP versión 2 existe un método para evitar el código Java en los archivos JSP. ¿Puede alguien decirme las líneas alternativas de JSP 2 y cómo se llama esta técnica?


22
@Koray Tugay, siempre que la variable de contador se declare en algún lugar antes de su uso, entonces es ciertamente válida ...
Sheldon R.

@SheldonR. Esto es válido: <% = counter ++%> o esto: <%! int contador = 0; int x = contador ++; %> pero no: <%! int contador = 0; contador ++; %>
Koray Tugay

@KorayTugay, lo que quise decir es que si el contador de variables se declaró en un bloque de script anterior, debería ser válido en un bloque posterior. Pero en última instancia, los programadores de J2EE en estos días deberían usar variables EL en lugar de scriptlets, de todos modos ...
Sheldon R.

Respuestas:


1972

El uso de scriptlets (esas <% %>cosas) en JSP está realmente desalentado desde el nacimiento de taglibs (como JSTL ) y EL ( Expression Language , esas ${}cosas) en 2001.

Las principales desventajas de los scriptlets son:

  1. Reusabilidad: no puede reutilizar scriptlets.
  2. Reemplazabilidad: no se pueden hacer scriptlets abstractos.
  3. OO-capacidad: no puede hacer uso de la herencia / composición.
  4. Depuración: si scriptlet lanza una excepción a mitad de camino, todo lo que obtienes es una página en blanco.
  5. Testabilidad: los scriptlets no se pueden probar en unidades.
  6. Mantenibilidad: por saldo se necesita más tiempo para mantener la lógica del código mezclado / desordenado / duplicado.

Sun Oracle también recomienda en las convenciones de codificación JSP para evitar el uso de scriptlets siempre que las clases (tag) puedan hacer la misma funcionalidad. Aquí hay varias citas de relevancia:

A partir de la especificación JSP 1.2, se recomienda encarecidamente utilizar la biblioteca de etiquetas estándar JSP (JSTL) en su aplicación web para ayudar a reducir la necesidad de scriptlets JSP en sus páginas. Las páginas que usan JSTL son, en general, más fáciles de leer y mantener.

...

Siempre que sea posible, evite los scriptlets JSP siempre que las bibliotecas de etiquetas proporcionen una funcionalidad equivalente. Esto hace que las páginas sean más fáciles de leer y mantener, ayuda a separar la lógica de negocios de la lógica de presentación y hará que sus páginas sean más fáciles de evolucionar a páginas de estilo JSP 2.0 (la especificación JSP 2.0 admite pero desestima el uso de scriptlets).

...

En el espíritu de adoptar el patrón de diseño modelo-vista-controlador (MVC) para reducir el acoplamiento entre el nivel de presentación de la lógica de negocios, los scriptlets JSP no deben usarse para escribir lógica de negocios. Por el contrario, los scriptlets JSP se usan si es necesario para transformar los datos (también llamados "objetos de valor") devueltos por el procesamiento de las solicitudes del cliente en un formato adecuado listo para el cliente. Incluso entonces, esto se haría mejor con un servlet controlador frontal o una etiqueta personalizada.


Cómo reemplazar los scriptlets depende completamente del único propósito del código / lógica. Más que a menudo, este código se debe colocar en una clase Java digna de confianza:

  • Si desea invocar el mismo código Java en cada solicitud, menos o más independientemente de la página solicitada, por ejemplo, verificando si un usuario ha iniciado sesión, luego implemente un filtro y escriba el código en consecuencia en el doFilter()método. P.ej:

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

    Cuando se asigna en un sitio apropiado que <url-pattern>cubre las páginas JSP de interés, entonces no necesita copiar y pegar el mismo fragmento de código en las páginas JSP generales.


  • Si desea invocar algún código Java para preprocesar una solicitud, por ejemplo, precargar una lista de una base de datos para mostrarla en alguna tabla, si es necesario en función de algunos parámetros de consulta, luego implemente un servlet y escriba el código correspondiente en el doGet()método. P.ej:

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

    De esta forma, lidiar con las excepciones es más fácil. No se accede a la base de datos en medio de la representación JSP, pero mucho antes de que se muestre la JSP. Todavía tiene la posibilidad de cambiar la respuesta cada vez que el acceso a la base de datos arroja una excepción. En el ejemplo anterior, la página predeterminada de error 500 se mostrará que de todos modos se puede personalizar por una <error-page>en web.xml.


  • Si desea invocar algún código Java para procesar posteriormente una solicitud, por ejemplo, procesar un envío de formulario, implemente un servlet y escriba el código correspondiente en el doPost()método. P.ej:

    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 esta manera tratar con diferentes destinos página de resultados es más fácil: volver a mostrar el formulario con los errores de validación en caso de un error (en este ejemplo particular se puede volver a mostrarlo usando ${message}en EL ), o simplemente tomar a la página de destino deseado en caso de éxito.


  • Si desea invocar algún código Java para controlar el plan de ejecución y / o el destino de la solicitud y la respuesta, implemente un servlet de acuerdo con el Patrón del controlador frontal del MVC . P.ej:

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

    O simplemente adopte un marco MVC como JSF , Spring MVC , Wicket , etc. para que termine con solo una página JSP / Facelets y una clase JavaBean sin la necesidad de un servlet personalizado.


  • Si desea invocar algún código Java para controlar el flujo dentro de una página JSP, debe tomar un taglib de control de flujo (existente) como el núcleo JSTL . Por ejemplo, mostrar List<Product>en una tabla:

    <%@ 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>

    Con etiquetas de estilo XML que se ajustan bien a todo ese HTML, el código es mejor legible (y por lo tanto mejor mantenible) que un montón de scriptlets con varias llaves de apertura y cierre ( "¿A dónde diablos pertenece esta llave de cierre?" ). Una ayuda fácil es configurar su aplicación web para que arroje una excepción siempre que se sigan utilizando scriptlets agregando la siguiente pieza a web.xml:

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

    En Facelets , el sucesor de JSP, que forma parte del marco MVC JSF proporcionado por Java EE , ya no es posible utilizar scriptlets . De esta manera, se te obliga automáticamente a hacer las cosas "de la manera correcta".


  • Si desea invocar algún código Java para acceder y mostrar datos de "back-end" dentro de una página JSP, debe usar EL (lenguaje de expresión), esas ${}cosas. Por ejemplo, volver a mostrar los valores de entrada enviados:

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

    La ${param.foo}muestra el resultado de request.getParameter("foo").


  • Si desea invocar algún código Java de utilidad directamente en la página JSP (generalmente public staticmétodos), debe definirlos como funciones EL. Hay un taglib de funciones estándar en JSTL, pero también puede crear fácilmente funciones usted mismo . Aquí hay un ejemplo de cómo JSTL fn:escapeXmles útil para prevenir ataques XSS .

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

    Tenga en cuenta que la sensibilidad XSS no está relacionada de ninguna manera específicamente con Java / JSP / JSTL / EL / lo que sea, este problema debe tenerse en cuenta en cada aplicación web que desarrolle. El problema de los scriptlets es que no proporciona ninguna forma de prevención integrada, al menos no utilizando la API Java estándar. El sucesor de JSP, Facelets, ya tiene un escape de HTML implícito, por lo que no debe preocuparse por los agujeros XSS en Facelets.

Ver también:


117
+1 Gran respuesta. Pero no se vuelva dogmático, a veces usar scriptlets está bien, pero esa debería ser la excepción que pruebe la regla.
svachon

26
@svachon: los scriptlets son útiles para la creación rápida de prototipos / pruebas. Hasta donde sé, solo hay un uso de producción "legítimo" de un scriptlet, es decir, <% response.getWriter().flush(); %>entre </head>y <body>para mejorar el rendimiento del análisis de páginas web en el navegador web. Pero este uso es completamente insignificante cuando el tamaño del búfer de salida en el lado del servidor es bajo (1 ~ 2 KB). Ver también este artículo .
BalusC

55
@BalusC Algunas veces me he quedado atascado con clases de Java que no siguieron el patrón getter / setter. En mi humilde opinión, es un caso donde un scripltet hace el trabajo.
svachon

41
@svachon: envolvería esas clases con clases javabean propias y las usaría en su lugar.
BalusC

31
Fue una respuesta bastante buena, pero las partes doGet y doPost son engañosas. ¡Esos métodos son para manejar métodos de solicitud específicos (HEAD, GET y POST) y no son para solicitudes de "procesamiento previo" o "procesamiento posterior"!
MetroidFan2002

225

Como salvaguarda: deshabilite los scriptlets para siempre

Como otra pregunta está discutiendo, puede y siempre debe deshabilitar los scriptlets en suweb.xml descriptor de aplicación web.

Siempre haría eso para evitar que cualquier desarrollador agregue scriptlets, especialmente en compañías más grandes donde perderá la visión general tarde o temprano. La web.xmlconfiguración se ve así:

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

44
¿Esto también deshabilita los comentarios de scriptlet ?: <%-- comment that i don't want in the final HTML --%>. Me resulta útil utilizar estos comentarios en lugar de los comentarios HTML.
David Lavender

16
@MrSpoon buscó una respuesta para usted. Según esta respuesta + comentario , esto desactiva los scriptlets <% %>, las expresiones <%! %>scriptlet y las declaraciones scriptlet <%= %>. Eso significa que las directivas <%@ %>y comentarios <%-- --%>permanecen habilitados y utilizables, por lo que aún puede hacer comentarios e incluirlos.
Martin Carney

3
La desactivación de las directivas de scriptlet sería terrible: recortar espacios en blanco es invaluable para interactuar con sistemas heredados que se asustan con espacios en blanco adicionales.
corsiKa

108

JSTL ofrece etiquetas para condicionales, bucles, conjuntos, gets, etc. Por ejemplo:

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

JSTL funciona con atributos de solicitud: un Servlet los establece a menudo en la solicitud, que se reenvía al JSP.


2
¿Por qué dice que JSTL funciona con atributos de solicitud? Pueden trabajar con atributos en cualquier ámbito, ¿no?
Koray Tugay

60

No estoy seguro si lo entiendo correctamente.

Deberías leer algo sobre MVC. Spring MVC & Struts 2 son las dos soluciones más comunes.


29
MVC se puede implementar con servlets / jsp utilizando muchas de las técnicas anteriores sin Spring o Struts.
stepanian

18
¿Cómo responde la pregunta?
xyz

54

Puede usar etiquetas JSTL junto con expresiones EL para evitar mezclar código Java y 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>

34

También hay marcos basados ​​en componentes como Wicket que generan mucho HTML para usted. Las etiquetas que terminan en el HTML son extremadamente básicas y prácticamente no hay lógica que se mezcle. El resultado son páginas HTML casi vacías con elementos HTML típicos. La desventaja es que hay muchos componentes en la API de Wicket para aprender y algunas cosas pueden ser difíciles de lograr con esas limitaciones.


33

En el patrón arquitectónico MVC, los JSP representan la capa Vista. Incrustar código Java en JSP se considera una mala práctica. Puede usar JSTL , freeMarker , velocidad con JSP como "motor de plantillas". El proveedor de datos para esas etiquetas depende de los marcos con los que está tratando. Struts 2y webworkcomo implementación para MVC Pattern utiliza OGNL "una técnica muy interesante para exponer Beans Properties a JSP".


27

La experiencia ha demostrado que los JSP tienen algunas deficiencias, una de las cuales es difícil evitar mezclar el marcado con el código real.

Si puede, considere usar una tecnología especializada para lo que necesita hacer. En Java EE 6 hay JSF 2.0, que proporciona muchas características interesantes, como pegar beans Java junto con páginas JSF a través del #{bean.method(argument)}enfoque.


3
Respuesta anterior, pero no puedo resistirme a decir que JSF es uno de los inventos más horrendos en el espacio Java. Intente hacer un enlace único (como HTTP GET) y entenderá por qué.
Alex

@Alex pero aún mejor. Siéntase libre de recomendar algo aún mejor.
Thorbjørn Ravn Andersen

26

Si simplemente desea evitar los inconvenientes de la codificación Java en JSP, puede hacerlo incluso con scriplets. Simplemente siga alguna disciplina para tener Java mínimo en JSP y casi ningún cálculo y lógica en la página 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>

26

Aprenda a personalizar y escribir sus propias etiquetas con JSTL

Tenga en cuenta que EL es EviL (excepciones de tiempo de ejecución, refactorización)
Wicket también puede ser malo (rendimiento, difícil para aplicaciones pequeñas o nivel de vista simple)

Ejemplo de java2s ,

Esto debe agregarse a la aplicación web web.xml

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

crear archivo: java2s.tld en / 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>

compile el siguiente código en 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;
    }
}

Inicie el servidor y cargue bodyContent.jsp en el navegador

<%@ 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>

aunque la reutilización de los componentes está bien se dirige a algún campo
tomasb

25

Wicket también es una alternativa que separa completamente Java de HTML, por lo que un diseñador y un programador pueden trabajar juntos y en diferentes conjuntos de código con poca comprensión el uno del otro.

Mira Wicket.


23

Hiciste una buena pregunta y aunque obtuviste buenas respuestas, te sugiero que te deshagas de JSP. Es una tecnología obsoleta que eventualmente morirá. Use un enfoque moderno, como los motores de plantillas. Tendrá una separación muy clara de las capas empresariales y de presentación, y ciertamente no habrá código Java en las plantillas, por lo que puede generar plantillas directamente desde el software de edición de presentaciones web, en la mayoría de los casos aprovechando WYSIWYG.

Y, ciertamente, manténgase alejado de los filtros y el procesamiento previo y posterior, de lo contrario, puede enfrentar dificultades de soporte / depuración ya que siempre no sabe de dónde obtiene el valor la variable.


99
JSP es en sí mismo un motor de plantillas
WarFox

1
-1 - Hay muchas razones completamente válidas para usar filtros, preprocesadores y postprocesadores. Sí, puede terminar con valores que parecen misteriosos, pero no si comprende su arquitectura.
RustyTheBoyRobot

21

Para evitar el código Java en archivos JSP, Java ahora proporciona bibliotecas de etiquetas como JSTL. Java también ha creado JSF en el que puede escribir todas las estructuras de programación en forma de etiquetas.


21

No importa cuánto trate de evitar, cuando trabaje con otros desarrolladores, algunos de ellos seguirán prefiriendo scriptlet y luego insertarán el código malvado en el proyecto. Por lo tanto, configurar el proyecto en el primer signo es muy importante si realmente desea reducir el código de scriptlet. Hay varias técnicas para superar esto (incluidos varios marcos que otros mencionaron). Sin embargo, si prefiere la forma JSP pura, utilice el archivo de etiqueta JSTL. Lo bueno de esto es que también puede configurar páginas maestras para su proyecto, por lo que las otras páginas pueden heredar las páginas maestras

Cree una página maestra llamada base.tag debajo de sus WEB-INF / tags con el siguiente contenido

<%@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>

En esta página mater, creé un fragmento llamado "título", para que en la página secundaria, pudiera insertar más códigos en este lugar de la página maestra. Además, la etiqueta<jsp:doBody/> será reemplazada por el contenido de la página secundaria

Cree una página secundaria (child.jsp) en su carpeta 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>se usa para especificar la página maestra que desea usar (que es base.tag en este momento). Todo el contenido dentro de la etiqueta <jsp:body>aquí reemplazará el <jsp:doBody/>de su página maestra. Su página secundaria también puede incluir cualquier etiqueta lib y puede usarla normalmente como la otra mencionada. Sin embargo, si usa algún código de scriptlet aquí ( <%= request.getParameter("name") %>...) e intenta ejecutar esta página, obtendrá unJasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here . Por lo tanto, no hay forma de que otras personas puedan incluir el código maligno en el archivo jsp

Llamando a esta página desde su controlador:

Puede llamar fácilmente al archivo child.jsp desde su controlador. Esto también funciona bien con el marco de struts


"No importa cuánto intente evitar, cuando trabaje con otros desarrolladores, algunos de ellos seguirán prefiriendo scriptlet y luego insertarán el código maligno en el proyecto". Consulte la respuesta "Como salvaguarda: deshabilite los scriptlets para siempre".
Lluis Martinez


18

Simplemente use la etiqueta JSTL y la expresión EL.


17

Si alguien está realmente en contra de la programación en más lenguajes que uno , sugiero GWT, teóricamente puede evitar todos los elementos JS y HTML, porque Google Toolkit transforma todo el cliente y el código compartido a JS, por lo que no tendrá problemas con ellos. tiene un servicio web sin codificación en ningún otro idioma. Incluso puede usar algunos CSS predeterminados desde algún lugar, ya que lo proporcionan las extensiones (smartGWT o Vaadin). No necesitas aprender docenas de anotaciones.

Por supuesto, si lo desea, puede hackear las profundidades del código e inyectar JS y enriquecer su página HTML, pero realmente puede evitarlo si lo desea, y el resultado será bueno, ya que se escribió en cualquier otro marco. Digo que vale la pena intentarlo, y el GWT básico está bien documentado.

Y, por supuesto, muchos programadores compañeros describieron o recomendaron varias otras soluciones. GWT es para personas que realmente no quieren lidiar con el elemento web o minimizarlo.


1
Realmente no responde la pregunta del OP.
Evan Donovan

1
@EvanDonovan bien, prácticamente da una respuesta. No necesita meterse con los códigos Java que se mezclan con otros idiomas. Admito que usa Java para la codificación, pero se traducirá a JS sin llamadas Java. Pero el alcance de la pregunta es cómo evitar el caos del clásico JSP. Y la tecnología GWT lo resuelve. Agregué esta respuesta ya que nadie la mencionó, pero es relevante ya que es una alternativa a JSP. No quería responder a todo el alcance de la pregunta, sino agregar una información valiosa para las personas que buscan alternativas.
CsBalazsHungary

16

Una buena idea del mundo de Python son los lenguajes de atributos de plantilla ; TAL fue introducido por Zope (por lo tanto, también conocido como "Zope Page Templates", ZPT) y es un estándar, con implementaciones en PHP, XSLT y Java también (he usado las encarnaciones de Python / Zope y PHP). En esta clase de lenguajes de plantillas, un ejemplo anterior podría verse así:

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

El código se ve como HTML ordinario (o XHTML) más algunos atributos especiales en un espacio de nombres XML; se puede ver con un navegador y un diseñador puede ajustarlo de forma segura. Hay soporte para macros y también para i18n:

<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 las traducciones del contenido están disponibles, se utilizan.

Sin embargo, no sé mucho sobre la implementación de Java .


1
Desde diciembre de 2009, JSP ha sido sucedido por Facelets, que admite estas cosas. Facelets también está basado en XML. Consulte también, entre otros, el capítulo Facelets en el tutorial y las ui:xxxetiquetas de Java EE 6 en Facelts VDL .
BalusC

No conozco Facelets muy bien, pero IIRC se trata de escribir clases que implementen elementos XML personalizados. La forma TAL / ZPT es tener plantillas que contienen HTML verdadero (X) con atributos especiales que llenan o reemplazan los elementos originales; por lo tanto, puede ver la plantilla de trabajo y ver un prototipo con buen contenido ficticio. No estoy seguro de que Facelets permita modificar los elementos HTML originales (sin un espacio de nombres adicional) utilizando atributos personalizados.
Tobias

Acabo de echar otro vistazo a estas cosas de Facelets. Contiene todo tipo de instalaciones de validación, etc. y, por lo tanto, sigue una filosofía completamente diferente a la de TAL. La forma TAL es: "Mantenga la lógica fuera de la plantilla lo más limpiamente posible; haga que el controlador que lo alimenta haga todas las cosas complicadas". Nunca le dará una plantilla de Facelets a un diseñador para que la modifique; Simplemente no es posible. En cuanto al contenido generado, es como usar tal:replace="structure (expression)"atributos todo el tiempo.
Tobias


14

Claro, sustitúyalo <%! counter++; %>por una arquitectura de productor-consumidor de eventos, donde se notifique a la capa empresarial sobre la necesidad de incrementar el contador, reaccione en consecuencia y notifique a los presentadores para que actualicen las vistas. Hay varias transacciones de bases de datos involucradas, ya que en el futuro necesitaremos conocer el valor nuevo y antiguo del contador, quién lo ha incrementado y con qué propósito en mente. Obviamente, la serialización está involucrada, ya que las capas están completamente desacopladas. Podrá incrementar su contador sobre RMI, IIOP, SOAP. Pero solo se requiere HTML, que no se implementa, ya que es un caso tan mundano. Su nuevo objetivo es alcanzar 250 incrementos por segundo en su nuevo y brillante servidor E7 de 64 GB de RAM.

Tengo más de 20 años en programación, la mayoría de los proyectos fallan antes del sexteto: Reusabilidad Reemplazabilidad OO-capacidad Debuggability Testability La mantenibilidad es incluso necesaria. Otros proyectos, dirigidos por personas que solo se preocupaban por la funcionalidad, fueron extremadamente exitosos. Además, la estructura rígida del objeto, implementada demasiado temprano en el proyecto, hace que el código no pueda adaptarse a los cambios drásticos en las especificaciones (también conocido como ágil).

Por lo tanto, considero como dilación la actividad de definir "capas" o estructuras de datos redundantes, ya sea al principio del proyecto o cuando no se requiera específicamente.  


11

Técnicamente, los JSP se convierten a Servlets durante el tiempo de ejecución . JSP se creó inicialmente con el propósito de desacoplar la lógica empresarial y la lógica de diseño, siguiendo el patrón MVC. Entonces, JSP son técnicamente todos los códigos de Java durante el tiempo de ejecución. Pero para responder a la pregunta, las bibliotecas de etiquetas generalmente se usan para aplicar lógica (eliminar códigos Java) a páginas JSP.


8

Si usamos los siguientes elementos en una aplicación web de Java, el código de Java puede eliminarse del primer plano del JSP.

  1. Use la arquitectura MVC para la aplicación web

  2. Usar etiquetas JSP

    a. Etiquetas estándar

    si. Etiquetas personalizadas

  3. Lenguaje de expresión


8

¿Cómo evitar el código Java en archivos JSP?

Puede usar etiquetas de biblioteca de pestañas como JSTL además de Expression Language ( EL ). Pero EL no funciona bien con JSP. Por lo tanto, probablemente sea mejor soltar JSP por completo y usar Facelets .

Facelets es el primer lenguaje de declaración de página que no es JSP diseñado para JSF (Java Server Faces) que proporcionó un modelo de programación más simple y potente para los desarrolladores de JSF en comparación con JSP. Resuelve diferentes problemas que ocurren en JSP para el desarrollo de aplicaciones web.

ingrese la descripción de la imagen aquí

Fuente


Definitivamente apoyo esta respuesta. JSF con o sin Facelets. Pensé que desarrollar en JSP había cesado en gran parte hace más de 10 años. ¡La última vez que escribí JSP fue en 2000!
compromiso

4

Usar Scriptlets es una forma muy antigua y no se recomienda. Si desea generar directamente algo en sus páginas JSP, simplemente use Expression Language (EL) junto con JSTL .

También hay otras opciones, como usar un motor de plantillas como Velocity, Freemarker, Thymeleaf, etc. Pero usar JSP simple con EL y JSTL cumple mi propósito la mayor parte del tiempo y también parece el más simple para un principiante.

Además, tenga en cuenta que no es una práctica recomendada hacer lógica empresarial en la capa de vista, debe realizar sus lógicas comerciales en la capa de Servicio y pasar el resultado de salida a sus vistas a través de un Controlador.


3

Ya no se usa nada de eso, amigo mío, mi consejo es desacoplar la vista (css, html, javascript, etc.) del servidor.

En mi caso, hago que mis sistemas manejen la vista con Angular y los datos necesarios se traen del servidor utilizando los servicios de descanso.

Créeme, esto cambiará la forma en que diseñas


3

Use el backbone, angular como el marco de javascript para el diseño de la interfaz de usuario y obtenga los datos utilizando la API de resto. Esto eliminará la dependencia de Java de la interfaz de usuario por completo.


3

JSP 2.0 tiene una característica llamada "Archivos de etiquetas" , puede escribir etiquetas sin javacódigo externo y tld. Necesita crear un .tagarchivo y ponerlo, WEB-INF\tagsincluso puede crear una estructura de directorio para empaquetar sus etiquetas.

Por ejemplo:

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

Úselo como

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

Además, puede leer el cuerpo de la etiqueta fácilmente

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

Úsalo

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

Las muestras son muy simples, pero puedes hacer muchas tareas complicadas aquí. Por favor, considere que puede utilizar otras etiquetas (por ejemplo: JSTLque se controlan las etiquetas como if/forEcah/chosenla manipulación de texto como format/contains/uppercase, o incluso etiquetas de SQL select/update), pasar todos los parámetros tipo, por ejemplo Hashmap, el acceso session, request... en el archivo de etiqueta también.

Los archivos de etiquetas son tan fáciles de desarrollar que no fue necesario reiniciar el servidor al cambiarlos, como los archivos JSP. Esto los hace fáciles de desarrollar.

Incluso si usa un marco como Struts 2, que tiene muchas etiquetas buenas, puede encontrar que tener sus propias etiquetas puede reducir mucho su código. Puede pasar sus parámetros de etiqueta a puntales y de esta manera personalizar su etiqueta de marco.

Puede usar la etiqueta no solo para evitar Java, sino también para minimizar sus códigos HTML. Yo mismo trato de revisar los códigos HTML y construir muchas etiquetas apenas veo duplicados de códigos en mis páginas.

(Incluso si termina usando Java en su código JSP, lo cual espero que no, puede encapsular ese código en una etiqueta)


1

Como dicen muchas respuestas, use JSTL o cree sus propias etiquetas personalizadas. Aquí hay una buena explicación sobre la creación de etiquetas personalizadas


1
  1. Haga sus valores y parámetros dentro de sus clases de servlet
  2. Obtenga esos valores y parámetros dentro de su JSP usando JSTL / Taglib

¡Lo bueno de este enfoque es que su código también es HTML como código!


0

Al usar etiquetas JSTL junto con la expresión EL, puede evitar esto. Ponga lo siguiente en su página 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" %>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.