sintaxis scriptlets imprimir ejemplos ejemplo codigo basico java jsp sitemesh scriptlet

java - scriptlets - jsp y html



¿Cómo evitar el uso de scriptlets en mi página JSP? (7)

Me han dicho que el uso de scriptlets (<% = ...%>) en mis páginas JSP no es una gran idea.

¿Alguien con un poco más de experiencia java / jsp, por favor dame algunos consejos sobre cómo cambiar este código para que sea más ''mejor práctica'', sea lo que sea?

Esta JSP es en realidad mi página decoradora principal de sitemesh. Básicamente, mi diseño web tiene una pestaña y un submenú, y deseo resaltar de algún modo la pestaña actual y mostrar el submenú correcto mirando el URI de solicitud actual.

<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> <html> <head> <title>My Events - <decorator:title /></title> <link href="<%= request.getContextPath() %>/assets/styles.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="tabs"> <a <%= request.getRequestURI().contains("/events/") ? "class=''selected''" : "" %> href=''<%= request.getContextPath() %>/events/Listing.action''>Events</a> <a <%= request.getRequestURI().contains("/people/") ? "class=''selected''" : "" %> href=''<%= request.getContextPath() %>/people/Listing.action''>People</a> </div> <div class="submenu"> <% if(request.getRequestURI().contains("/events/")) { %> <a href="Listing.action">List of Events</a> |<a href="New.action">New Event</a> <% } %> <% if(request.getRequestURI().contains("/people/")) { %> <a href="Listing.action">List of People</a> |<a href="New.action">New Person</a> <% } %> &nbsp; </div> <div class="body"> <decorator:body /> </div> </body> </html>

Gracias a todos


Como un lado, ¿es <%= request.getContextPath() %> un uso aceptable de scriptlets que no está mal visto tanto?

Puede que esta sea una opinión impopular, pero si todo lo que hace son condicionales simples e inserciones de texto, no puedo encontrar muchas fallas en el uso de scriptlets. (Tenga en cuenta si )

Probablemente usaría JSTL y el lenguaje de expresión, pero sobre todo porque puede ser menos tipeo, y el soporte IDE puede ser mejor (pero un buen IDE JSP también puede encontrar corchetes de cierre faltantes y cosas así).

Pero fundamentalmente (como en "mantener la lógica fuera de las plantillas") no veo ninguna diferencia entre

<% if(request.getRequestURI().contains("/events/")) { %>

y

${fn:contains(pageContext.request.requestURI, ''/events/'')


Creo que ayuda más si ves con tus propios ojos que realmente se puede hacer completamente sin scriptlets.

Aquí hay una reescritura 1 en 1 con la ayuda de, entre otros, JSTL (simplemente suelta jstl-1.2.jar en /WEB-INF/lib ) core y functions taglib:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <html> <head> <title>My Events - <decorator:title /></title> <link href="${pageContext.request.contextPath}/assets/styles.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="tabs"> <a ${fn:contains(pageContext.request.requestURI, ''/events/'') ? ''class="selected"'' : ''''} href="${pageContext.request.contextPath}/events/Listing.action">Events</a> <a ${fn:contains(pageContext.request.requestURI, ''/people/'') ? ''class="selected"'' : ''''} href="${pageContext.request.contextPath}/people/Listing.action">People</a> </div> <div class="submenu"> <c:if test="${fn:contains(pageContext.request.requestURI, ''/events/'')}"> <a href="Listing.action">List of Events</a> |<a href="New.action">New Event</a> </c:if> <c:if test="${fn:contains(pageContext.request.requestURI, ''/people/'')}"> <a href="Listing.action">List of People</a> |<a href="New.action">New Person</a> </c:if> &nbsp; </div>

Aquí hay una reescritura más optimizada, tenga en cuenta que utilicé c:set en "caché" resultados de expresión para reutilizar y que utilizo la etiqueta HTML <base> para evitar poner la ruta de contexto en cada enlace (basta con hacer todas las URL relativas en su página web relativas a ¡sin la barra inicial!):

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <c:set var="isEvents" value="${fn:contains(pageContext.request.requestURI, ''/events/'')}" /> <c:set var="isPeople" value="${fn:contains(pageContext.request.requestURI, ''/people/'')}" /> <html> <head> <title>My Events - <decorator:title /></title> <base href="${pageContext.request.contextPath}"> <link href="assets/styles.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="tabs"> <a ${isEvents ? ''class="selected"'' : ''''} href="events/Listing.action">Events</a> <a ${isPeople ? ''class="selected"'' : ''''} href="people/Listing.action">People</a> </div> <div class="submenu"> <c:if test="${isEvents}"> <a href="Listing.action">List of Events</a>|<a href="New.action">New Event</a> </c:if> <c:if test="${isPeople}"> <a href="Listing.action">List of People</a>|<a href="New.action">New Person</a> </c:if> &nbsp; </div>

En realidad, puede optimizarse más si recopila todos los valores "codificados" como events y people y vincula textos en un Map en el ámbito de la aplicación y utiliza debajo de cada JSTL <c:forEach> para mostrar las pestañas.

En cuanto a su pregunta real , puede deshabilitar scriptlets (y obtener errores de tiempo de ejecución sobre su uso) al agregar la siguiente entrada en web.xml de web.xml . Puede ayudar a detectar los scriptlets supervisados.

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

Para obtener más información sobre EL, consulte el tutorial de Java EE parte II capítulo 5 . Los objetos EL implícitos, como ${pageContext} se describen here . Para obtener más información sobre JSTL, consulte el tutorial de Java EE, parte II, capítulo 7 . Tenga en cuenta que JSTL y EL son dos cosas separadas. JSTL es un taglib estándar y EL solo permite acceder a los datos de back-end programáticamente. Aunque normalmente se usa en taglibs como JSTL, también se puede usar de forma independiente en el texto de la plantilla.


Esta no es una respuesta directa a su pregunta (y ya hay muchas buenas, así que no intentaré agregarle más), pero mencionó:

¿Alguien con un poco más de experiencia java / jsp, por favor dame algunos consejos sobre cómo cambiar este código para que sea más ''mejor práctica'', sea lo que sea ?

En mi opinión, la mejor práctica, con respecto a JSP, es que debe usarse estrictamente como un motor de plantillas , y no más (es decir, sin lógica de negocios). Usar JSTL, como muchos señalaron, definitivamente te ayuda a llegar, pero incluso con JSTL, es fácil hacer mucho en un JSP.

Personalmente, me gusta seguir las reglas establecidas en Aplicación de la estricta Vista de Modelo-Vista de Motores de Templating por Terence Parr al desarrollar en JSP. El documento menciona el propósito de las plantillas de motores (separando el modelo y la vista) y las características de un buen motor de plantillas. Da un buen vistazo a JSP y señala formas en que no es un buen motor de plantillas. No es sorprendente que JSP sea básicamente demasiado poderoso y permita a los desarrolladores hacer demasiado. Recomiendo leer este documento, y lo ayudará a restringirse a las partes "buenas" de JSP.

Si solo lees una sección en ese documento, lee el capítulo 7, que incluye las siguientes reglas:

  1. la vista no puede modificar el modelo, ya sea alterando directamente los objetos de datos del modelo o invocando métodos en el modelo que causan efectos secundarios. Es decir, una plantilla puede acceder a los datos del modelo e invocar métodos, pero tales referencias deben ser libres de efectos secundarios. Esta regla surge parcialmente porque las referencias de datos deben ser insensibles a la orden. Ver la Sección 7.1.
  2. la vista no puede realizar cálculos sobre valores de datos dependientes porque los cálculos pueden cambiar en el futuro y deben estar perfectamente encapsulados en el modelo en cualquier caso. Por ejemplo, la vista no puede calcular precios de venta de libros como "$ price * .90". Para ser independiente del modelo, la vista no puede hacer suposiciones sobre el significado de los datos.
  3. la vista no puede comparar valores de datos dependientes , pero puede probar las propiedades de los datos, como la presencia / ausencia o la longitud de un valor de datos multivalor. Las pruebas como $ bloodPressure <120 deben trasladarse al modelo ya que a los médicos les gusta seguir reduciendo la presión sistólica máxima sobre nosotros. Las expresiones en la vista deben ser reemplazadas por una prueba de presencia de un valor que simula un booleano como $ bloodPressureOk! = Null. La salida de la plantilla puede ser condicional en los datos del modelo y las computaciones, el condicional solo tiene que calcularse en el modelo . Incluso las pruebas simples que hacen que los valores negativos sean rojos deben calcularse en el modelo; el nivel correcto de abstracción es usualmente algo de un nivel más alto, como "el departamento x está perdiendo dinero".
  4. la vista no puede hacer suposiciones de tipos de datos. Algunas suposiciones de tipo son obvias cuando la vista asume que un valor de datos es una fecha, por ejemplo, pero aparecen suposiciones de tipos más sutiles: si una plantilla asume que $ ID de usuario es un número entero, el programador no puede cambiar este valor para que sea no -númrico en el modelo sin romper la plantilla. Esta regla prohíbe la indexación de matrices como colorCode [$ topic] y $ name [$ ID] La vista además no puede invocar métodos con argumentos porque (estática o dinámicamente) existe un tipo de argumento supuesto, a menos que se pueda garantizar el modelo método meramente los trató como objetos. Además de los diseñadores gráficos no son programadores; esperar que invoquen métodos y sepan qué pasar es poco realista.
  5. los datos del modelo no deben contener información de visualización o diseño. El modelo no puede pasar ninguna información de visualización a la vista disfrazada de valores de datos. Esto incluye no pasar el nombre de una plantilla para aplicarla a otros valores de datos.

Incidentalmente, Terence ha creado su propio motor de creación de plantillas llamado String Template, que supuestamente hace un muy buen trabajo al aplicar estas reglas. No tengo experiencia personal con él, pero me encantaría verificarlo en mi próximo proyecto.


La alternativa preferida a los scriptlets es el lenguaje de expresión JSTL; here una buena visión general. Necesitarás agregar el taglib así:

<%@ taglib uri=''http://java.sun.com/jsp/jstl/core'' prefix=''c'' %>

Como ejemplo, JSTL proporciona un conjunto de objetos implícitos que le brindan lo que necesita; el que quiere es pageContext.request .

Entonces puede reemplazar <%request.getRequestURI%> con ${pageContext.request.requestURI} .

Puede hacer condicionales usando etiquetas <c:if> .


Los scriptlets no son lo peor del mundo. Una consideración importante es pensar quién mantendrá el código. Si sus diseñadores web no tienen mucha experiencia en Java, probablemente sea mejor que vaya con las bibliotecas de etiquetas. Sin embargo, si los desarrolladores de Java están haciendo el mantenimiento, puede ser más fácil para ellos ir con scriptlets.

Si termina utilizando una biblioteca de etiquetas y JSTL, está esperando que el mantenedor también aprenda la biblioteca de etiquetas y conozca JSTL. Algunos desarrolladores estarán de acuerdo con esto, ya que es una habilidad que quieren o ya tienen, pero para algunos desarrolladores que solo tienen que lidiar con JSP cada pocos meses más o menos, puede ser mucho menos doloroso trabajar con scriptlets escritos claramente escritos en , familiar de Java.


Necesitarás usar un poco de framework web. O al menos algún taglib conveniente. O un enginge de plantillas como FreeMarker .

Marcos de anuncios:

Si te gusta la forma de codificación JSP, te sugiero Struts 2 .

<s:if test="%{false}"> <div>Will Not Be Executed</div> </s:if> <s:elseif test="%{true}"> <div>Will Be Executed</div> </s:elseif> <s:else> <div>Will Not Be Executed</div> </s:else>

Luego está el JSF orientado a componentes.

Si le gusta OOP y codifica todo en Java, pruebe Apache Wicket (mi favorito) o Google Web Toolkit .


Puede comenzar utilizando bibliotecas de etiquetas. Puede usar la biblioteca de etiquetas estándar JSTL para hacer la mayoría de las cosas comunes para las que necesita los scriplets. Hay muchas otras bibliotecas de etiquetas más ricas que se utilizan como en el marco struts2 o de apache.

p.ej

<c:if test="${your condition}"> Your Content </c:if>

reemplazaría tus declaraciones if.