jsp - redireccionar - servlet ventajas y desventajas
Funciones ocultas de JSP/Servlet (1)
Nota: Me resulta difícil pensar en cualquier "característica oculta" para JSP / Servlet. En mi opinión, "mejores prácticas" es una mejor redacción y puedo pensar en alguna de ellas. También realmente depende de tu experiencia con JSP / Servlet. Después de años de desarrollo, ya no ves esas "características ocultas". De cualquier modo, enumeraré algunas de esas pequeñas "mejores prácticas" de las cuales, en años, descubrí que muchos principiantes no son plenamente conscientes de ello. Esos serían categorizados como "características ocultas" en el ojo de muchos principiantes. De todos modos, aquí está la lista :)
Ocultar páginas JSP del acceso directo
Al colocar los archivos JSP en la carpeta /WEB-INF
, efectivamente los oculta del acceso directo, por ejemplo, en http://example.com/contextname/WEB-INF/page.jsp
. Esto dará como resultado un 404
. A continuación, solo puede acceder a ellos mediante un RequestDispatcher
en Servlet o utilizando jsp:include
.
Solicitud de preproceso para JSP
La mayoría conoce el doPost()
Servlet para publicar una solicitud (un envío de formulario), pero la mayoría no sabe que puede usar el método doGet()
Servlet para preprocesar una solicitud de JSP. Por ejemplo:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Item> items = itemDAO.list();
request.setAttribute("items", items);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
}
que se utiliza para precargar algunos datos tabulares que se mostrarán con la ayuda de c:forEach
de JSTL:
<table>
<c:forEach items="${items}" var="item">
<tr><td>${item.id}</td><td>${item.name}</td></tr>
</c:forEach>
</table>
Asigne dicho servlet a un url-pattern
de url-pattern
de /page
(o /page/*
) y solo invoque http://example.com/contextname/page
mediante la barra de direcciones del navegador o un enlace simple de vanilla para ejecutarlo. Ver también p . Ej. DoGet y doPost en Servlets .
Dinámico incluye
Puede usar EL en jsp:include
:
<jsp:include page="/WEB-INF/${bean.page}.jsp" />
El bean.getPage()
solo puede devolver un nombre de página válido.
EL puede acceder a cualquier getter
EL no requiere por sí mismo que el objeto a ser accedido sea un Javabean completo . La presencia de un método no-arg que está prefijado con get
o is
es más que suficiente para acceder a él en EL. P.ej:
${bean[''class''].name}
Esto devuelve el valor de bean.getClass().getName()
donde el método getClass()
es realmente heredado de Object#getClass()
. Tenga en cuenta que la class
se especifica con "nota de corchete" []
por los motivos mencionados aquí instancia de verificación en el lenguaje de expresión EL .
${pageContext.session.id}
Esto devuelve el valor de pageContext.getSession().getId()
que es útil en ao ¿Puede un applet comunicarse con una instancia de un servlet ?
${pageContext.request.contextPath}
Esto devuelve el valor de pageContext.getRequest().getContextPath()
que es útil en ao ¿Cómo usar rutas relativas sin incluir el nombre de raíz de contexto?
EL también puede acceder a Mapas
La siguiente notación EL
${bean.map.foo}
resuelve a bean.getMap().get("foo")
. Si la clave del Map
contiene un punto, puede usar la "notación del paréntesis" []
con una clave entre comillas:
${bean.map[''foo.bar'']}
que se resuelve en bean.getMap().get("foo.bar")
. Si desea una clave dinámica, use la notación de corchete también, pero luego sin comillas:
${bean.map[otherbean.key]}
que se resuelve en bean.getMap().get(otherbean.getKey())
.
Iterar sobre el mapa con JSTL
Puede usar c:forEach
para iterar sobre un Map
. Cada iteración proporciona un Map.Entry
que a su vez tiene los getKey()
y getValue()
(para que pueda acceder a él en EL por ${entry.key}
y ${entry.value}
). Ejemplo:
<c:forEach items="${bean.map}" var="entry">
Key: ${entry.key}, Value: ${entry.value} <br>
</c:forEach>
Véase también, por ejemplo, Depuración con jstl: ¿cómo exactamente?
Obtener la fecha actual en JSP
Puede obtener la fecha actual con jsp:include y formatearlo con la ayuda de JSTL fmt:formatDate
<jsp:useBean id="date" class="java.util.Date" />
...
<p>Copyright © <fmt:formatDate value="${date}" pattern="yyyy" /></p>
Esto imprime (a partir de ahora) de la siguiente manera: "Copyright © 2010".
URL fáciles y amigables
Una manera fácil de tener URL amigables es hacer uso de HttpServletRequest#getPathInfo()
y las JSP ocultas en /WEB-INF
:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response);
}
Si asigna este servlet por ejemplo /pages/*
, una solicitud en http://example.com/contextname/pages/foo/bar
mostrará efectivamente /WEB-INF/foo/bar.jsp
. Puede dar un paso más al dividir el pathinfo en /
y solo tomar la primera parte como URL de la página JSP y el remanente como "acciones comerciales" (deje que el servlet actúe como un controlador de página ). Véase también, p. Ej., Aplicaciones basadas en la web de Design Patterns .
Volver a mostrar la entrada del usuario usando ${param}
El objeto EL implícito ${param}
que hace referencia a HttpServletRequest#getParameterMap()
se puede usar para volver a mostrar la entrada del usuario después de enviar un formulario en JSP:
<input type="text" name="foo" value="${param.foo}">
Esto básicamente hace lo mismo que request.getParameterMap().get("foo")
. Véase también, por ejemplo, ¿Cómo puedo conservar los valores de campo de formulario HTML en JSP después de enviar el formulario al servlet?
¡No olvides evitar de XSS! Ver el siguiente capítulo.
JSTL para evitar XSS
Para evitar que su sitio XSS de XSS , todo lo que necesita hacer es (re) mostrar los datos controlados por el usuario usando JSTL fn:escapeXml
o c:out
.
<p><input type="text" name="foo" value="${fn:escapeXml(param.foo)}">
<p><c:out value="${bean.userdata}" />
Alternar filas <table>
con LoopTagStatus
El atributo varStatus
de JSTL c:forEach
le proporciona un LoopTagStatus
que a su vez tiene varios métodos getter (¡que se pueden usar en EL!). Por lo tanto, para comprobar si hay filas pares, simplemente verifique si loop.getIndex() % 2 == 0
:
<table>
<c:forEach items="${items}" var="item" varStatus="loop">
<tr class="${loop.index % 2 == 0 ? ''even'' : ''odd''}">...</tr>
<c:forEach>
</table>
que efectivamente terminará en
<table>
<tr class="even">...</tr>
<tr class="odd">...</tr>
<tr class="even">...</tr>
<tr class="odd">...</tr>
...
</table>
Use CSS para darles un color de fondo diferente.
tr.even { background: #eee; }
tr.odd { background: #ddd; }
Rellenar una cadena separada por comas de la lista / matriz con LoopTagStatus
:
Otro método útil de LoopTagStatus
es el isLast()
:
<c:forEach items="${items}" var="item" varStatus="loop">
${item}${!loop.last ? '', '' : ''''}
<c:forEach>
Lo que resulta en algo como item1, item2, item3
.
Funciones EL
Puede declarar public static
métodos public static
utilidad public static
como funciones EL (como funciones JSTL ) para que pueda usarlos en EL. P.ej
package com.example;
public final class Functions {
private Functions() {}
public static boolean matches(String string, String pattern) {
return string.matches(pattern);
}
}
con /WEB-INF/functions.tld
que se ve así:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>Custom_Functions</short-name>
<uri>http://example.com/functions</uri>
<function>
<name>matches</name>
<function-class>com.example.Functions</function-class>
<function-signature>boolean matches(java.lang.String, java.lang.String)</function-signature>
</function>
</taglib>
que se puede usar como
<%@taglib uri="http://example.com/functions" prefix="f" %>
<c:if test="${f:matches(bean.value, ''^foo.*'')}">
...
</c:if>
Obtenga la URL de solicitud original y la cadena de consulta
Si el JSP se ha reenviado, puede obtener la URL de solicitud original,
${requestScope[''javax.servlet.forward.request_uri'']}
y la cadena de consulta de solicitud original por,
${requestScope[''javax.servlet.forward.query_string'']}
Eso fue todo lo lejos. Tal vez agregue algo más tarde o temprano.
Estoy interesado en tus trucos, etc. usados al escribir JSP / Servlet. Comenzaré:
Recientemente descubrí cómo puedes incluir el resultado de una etiqueta JSP en un atributo de otra etiqueta:
<c:forEach items="${items}">
<jsp:attribute name="var">
<mytag:doesSomething/>
</jsp:attribute>
<jsp:body>
<%-- when using jsp:attribute the body must be in this tag --%>
</jsp:body>
</c:forEach>