java - ejemplo - JSTL vs JSP Scriptlets
jstl maven (6)
Quiero que alguien explique algunos puntos en la sorprendente respuesta de BlausC en esta pregunta .
Dijo que los scriptlets tenían algunas desventajas, que son:
Reutilización: no puede reutilizar scriptlets. Mi pregunta: ¿cómo podría reutilizar el código JSTL?
Reemplazabilidad: no puede hacer que los scriptlets sean abstractos. ¿Qué significa abstracto y cómo podría JST convertirse en abstracto?
OO: no puedes hacer uso de la herencia / composición. ¿Cómo podría usar los paradigmas OO en JSTL?
Depuración: si un scriptlet arroja una excepción hasta la mitad, todo lo que obtiene es una página en blanco.
Testabilidad: los scriptlets no pueden ser probados en unidades. ¿Qué significa eso y cómo JSTL puede ser probado en unidades?
Mantenibilidad: por saldo, se necesita más tiempo para mantener la lógica del código mezclado / desordenado / duplicado. ¿Qué significa esto?
Lo último es lo que citó de la recomendación de Oracle:
Los scriptlets JSP no deben usarse para escribir lógica comercial.
En el patrón MVC, uso scriptlets solo en la capa de presentación. ¿Qué quiere decir él aquí?
Aquí hay una tabla que compara JSP y Facelets que puede ser útil para alguien, en alguna parte:
Depende del patrón que estés usando. Al usar MVC ( spring, struts, ... ) debe evitar el uso de scriptlets en su JSP, ya que representa la vista que debe contener etiquetas XHTML puras. JSTL es un lenguaje declarativo de algún tipo de XML, mientras que scriplet no lo es.
Particularmente, he usado JSTL en combinación con AJAX a través de un prototype para generar RIA sin necesidad de implementar otro patrón. Recientemente he visto este tipo de programación con ExtJS y DWR . En mi caso encontré que era necesario combinar JSTL y scriplets siempre prefiriendo JSTL cuando sea posible.
<!-- simple controller, each action is called by means of AJAX -->
<% String signExt="jpg"; %>
<% int r=0, iMaxRows=0, iMaxCols=0;%>
<c:choose>
<c:when test="${param.action == ''get_chrequest_profile_table_by_family_and_date''}">
<sql:query var="dataset">
CALL GetProfilesView(''<c:out value="${param.family_name}" />'', ''<c:out value="${param.reg_date}" />'')
</sql:query>
<c:set var="strElements"><c:out value="${dataset.rowCount}" /></c:set>
<%
String strElements = pageContext.getAttribute("strElements").toString();
int iElements = (int)Integer.valueOf(strElements).intValue();
String to = "";
%>
<table class="tb_profiles" id="tb_profiles" iElements="<%=iElements%>"
width="100%" frame=void border="0" cellPadding="0" cellSpacing="0" style="border-top: 3px solid gray; border-left: 1px solid gray">
<%for(int i=1, j=0, col=0; i<100; i++){%>
<tr>
<%for(j=0; j<4; j++, col++){%>
<c:set var="c" scope="page"><%=col%></c:set>
<td name=''<c:out value="${dataset.rows[c].chreqprofile_id}" />'' >
<table width="100%" frame="below" cellPadding="0" cellSpacing="0"style="border-right: 1px solid gray;">
<%if( col < iElements){%>
<tr style="height:10mm">
<td class="td_function" style="cursor:default;">
<c:out value="${dataset.rows[c].description}" />
</td>
</tr>
.................
<tr style="height:14mm">
<td class="td_signature" align="center" vAlign="middle">
<img class="img_signature"
src=''../xdata/signatures/<c:out value="${dataset.rows[c].responsible_name}"/>.<%=signExt%>''
alt=''<c:out value="${dataset.rows[c].email}" />''
/>
</td>
</tr>
.................
<c:set var="sMail"><c:out value="${dataset.rows[c].email}"/></c:set>
<% if( col < iElements-1){
to = to + pageContext.getAttribute("sMail").toString() + ",";
}else{
to = to + pageContext.getAttribute("sMail").toString();
}
%>
<%}else{%>
<tr style="height:10mm">
<td class="td_function" style="cursor:default;">x</td>
.............
</tr>
<%}%>
</table>
</td>
<%}%>
</tr>
<%
if( col >= iElements){break;}
}%>
</table>
<span id="span_mail_to" style="display:none;"><%=to%></span>
</c:when>
<c:when test="${param.action == ''functions_form_insert''}">
.............
</c:when>
</c:choose>
No deberías tener código scriptlet en JSPs. Recomiendo 100% JSTL y cero código de scriplet.
Las JSP deben ser puramente presentación. Ese es el beneficio oculto de escribir JSP utilizando solo JSTL, porque obtienen todos sus datos dinámicos en otro lugar. Deje que la capa de servicio tenga la lógica comercial y determine qué datos necesita el JSP.
Esto también responde a la pregunta de prueba de su unidad. No debería tener que probar JSP por unidad; esas serían pruebas de UI similares al Selenio. Si la lógica está en el nivel de servicio, es obvio cómo la prueba.
Las JSP no deben ser heredadas. Ciertamente puede componerlos juntos utilizando algo como SiteMesh, pero la herencia no tiene parte en sus JSP. Una vez que heredan de Servlet, la cadena debe finalizar.
Además, es una alternativa falsa. Ninguno de los dos debe requerir reutilización, herencia o pruebas unitarias. Pero eso no significa que no haya un ganador claro: es JSTL. Nadie debería estar usando scriptlets en JSPs, excepto por frases muy raras. Los scriptlets están pidiendo problemas.
En estos días prefiero Velocity como mi solución de plantilla de IU web para Java, mucho más que JSP. Solo es mi opinión.
No puedo hablar por BalusC pero, en general, creo que él estaba teniendo la idea de que este tipo de cosas deberían ser logradas por tu código Java normal (en las capas de Controlador y Modelo si estás en el tema completo de MVC).
No puede reutilizar literalmente las etiquetas JSP en un nivel individual, pero puede reutilizar las clases a las que llama.
JSTL no puede ser abstracto, pero sí puede ser el código Java normal (que quizás pueda invocar desde JSTL).
De nuevo, no puede hacer objetos útiles en jstl, pero puede hacerlo en todas las clases que se llaman.
JSTL por sí solo no es susceptible de prueba por la unidad. Pero las clases y los métodos que llamas son.
No veo que los scriplets sean demasiado malos, especialmente si sigues el patrón de diseño, trabajo mucho en spring mvc, en mi jsp solo obtengo los datos del modelo en scriplits, y se lo muestro al usuario usando un simple código java en html , siento que me da más libertad que JSTL.
Parece que solo se concentra en la parte de presentación y de control de flujo de los scriptlets, como en el uso de las instrucciones if
, for
y switch
y out.print()
. Pareces comparar scriptlets 1: 1 con JSTL. Esto está mal. No estaba hablando solamente de la parte de control de flujo (que de hecho debe ser reemplazada por JSTL), sino de escribir código Java en bruto en archivos JSP en general. Es decir, reunir parámetros de solicitud, validar y convertir valores, interactuar con la base de datos y otras clases / métodos de Java, etc. Todo lo que normalmente (indirectamente) se hace en un Servlet o Filtro.