jsp - tag - jstl url param
jsessionid se produce en todas las direcciones URL generadas por la etiqueta jstl<c: url..> (7)
Tengo un error extraño: cuando abro la página por primera vez en algún navegador, todas las referencias tienen el parámetro jsessionid (como <a href="/articles?name=art&jsessionid=5as45df4as5df"..>
).
Cuando presiono F5 o renuevo la página de otra forma, todo eso desaparece y todo funciona bien hasta que cierro el navegador (y todas las pestañas también deben cerrarse). Cuando lo vuelvo a abrir veo este extraño parámetro jsessionid.
Utilizo la etiqueta jstl <c:url..>
para crear todas las URL.
Hace algún tiempo, leí que jsessionid es una alternativa a las cookies si las cookies están deshabilitadas, pero las cookies están habilitadas y en realidad no uso cookies.
Aquí hay una solución desagradable en el sabor de un Filter
para que nunca vea el jsessionid en la URL siempre que el cliente admita cookies.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
if (session.isNew()) {
// New session? OK, redirect to encoded URL with jsessionid in it (and implicitly also set cookie).
res.sendRedirect(res.encodeRedirectURL(req.getRequestURI()));
return;
} else if (session.getAttribute("verified") == null) {
// Session has not been verified yet? OK, mark it verified so that we don''t need to repeat this.
session.setAttribute("verified", true);
if (req.isRequestedSessionIdFromCookie()) {
// Supports cookies? OK, redirect to unencoded URL to get rid of jsessionid in URL.
res.sendRedirect(req.getRequestURI().split(";")[0]);
return;
}
}
chain.doFilter(request, response);
}
Asignarlo en /*
o cualquier patrón de URL que requiera gestión de sesiones.
Como se explica en la respuesta de skaffman , no es un error. Es un comportamiento esperado .
En su pregunta, jsessionid se agrega como parámetro, que no es el caso.
Utilizando
<c:url value="/"/>
generará algo como lo siguiente: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA
.
Entonces usando
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
Generará
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, por lo que su servidor no puede encontrar el recurso disponible.
La mejor solución que encontré es usar ${pageContext.request.contextPath}
lugar de <c:url value="/"/>
. Entonces en el ejemplo anterior, tendrías
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
eso generará
/some/stylesheets/style.css
.
Esta solución es independiente del contenedor (mientras que el contenedor que cumple con la especificación del servlet v3, como Tomcat, no lo está). Filtrar la URL de respuesta se siente como un truco, porque necesita cambiar un comportamiento predeterminado. Pero todo depende de lo que necesita y quiere lograr.
En Tomcat 7 o en cualquier servidor que cumpla con la especificación de servlets v3, puede deshabilitar jsessionid en URL añadiendo el siguiente al archivo web.xml de su aplicación
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
Esto no es un error, es por diseño. Cuando se crea una nueva sesión, el servidor no está seguro de si el cliente admite cookies o no, por lo que genera una cookie y jsessionid en la URL. Cuando el cliente regresa por segunda vez y presenta la cookie, el servidor sabe que jsessionid no es necesario y lo descarta por el resto de la sesión. Si el cliente regresa sin cookies, entonces el servidor necesita continuar usando la reescritura de jsessionid.
No puede usar cookies explícitamente, pero sí tiene una sesión implícitamente, y el contenedor necesita rastrear esa sesión.
Lamentablemente, la única forma en que he encontrado esto es agregar un filtro a su aplicación que eliminará el parámetro jsessionid. Es particularmente molesto si está creando un sitio web público y quiere motores de búsqueda para indexar sus páginas.
No creo que Tomcat (si eso es lo que estás usando) se puede configurar para que no se agregue esto a tu url. No puedo decir por los otros servidores.
Sin embargo, tenga en cuenta que si crea el filtro y luego requiere la administración de la sesión y el usuario tiene las cookies desactivadas, se encontrará con problemas.
Si tiene una página contenedora común que todas las páginas usan (para mí era common.inc) puede agregar session="false"
a su <%@ page
para eliminar el sessionid.
Ejemplo common.inc
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="ab" tagdir="/WEB-INF/tags" %>
<c:set var="contextPath" scope="request" value="${ pageContext.request.contextPath }" />
<c:set var="assetPath" scope="request" value="/assets" />
<c:set var="debugEnabled" scope="request" value="${ applicationDebugProperties.debugEnabled }" />
Alternativamente, establezca el valor de c:url
en una variable y use c:out escapeXml="false"
para generar la variable y esto eliminará el sessionid.
Ejemplo:
<c:url value=${url} var="image"/>
<c:out var=${image} escapeXml="false"/>
Alternativamente, puede agregar esto a su configuración de Apache para truncar el sessionid.
ReWriteRule ^/(/w+);jsessionid=/w+$ /$1 [L,R=301]
ReWriteRule ^/(/w+/.go);jsessionid=/w+$ /$1 [L,R=301]
Una solución no es usar <c:url>
, sino usar ${request.contextPath}/path