Pregunta

Tengo un error extraño: cuando abro la página por primera vez en algún navegador, todas las referencias tienen el parámetro JSesionID (como <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

Cuando presiono F5 o actualizo la página de cualquier otra forma en que todo eso desaparezca y todo funciona bien hasta que cierre mi navegador (y todas las pestañas también deben cerrarse). Cuando lo abro de nuevo veo este extraño parámetro JSesionID.

Yo uso jstl <c:url..> Etiqueta para crear todas las URL.

He leído hace algún tiempo que JSesionID es una alternativa a las cookies si las cookies están deshabilitadas, pero las cookies están habilitadas y en realidad no uso cookies.

¿Fue útil?

Solución

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 el JSesionID en la URL. Cuando el cliente regresa la segunda vez y presenta la cookie, el servidor sabe que el JSesionID no es necesario y lo deja caer para el resto de la sesión. Si el cliente regresa sin cookie, entonces el servidor debe continuar utilizando la reescritura de JSesionID.

Es posible que no use explícitamente cookies, pero implícitamente tiene una sesión, y el contenedor necesita rastrear esa sesión.

Otros consejos

Como se explica en Respuesta de Skaffman, No es un error. Es un comportamiento esperado.

En su pregunta, el JSessionID se agrega como un parámetro, que no es el caso.
Usando
<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
, para que su servidor no pueda encontrar el recurso disponible.

La mejor solución que encontré es para usar ${pageContext.request.contextPath} en vez de <c:url value="/"/>. Entonces, en el ejemplo anterior, habrías
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
que generará
/some/stylesheets/style.css.

Esta solución es contenedor independiente (Mientras que el contenedor compatible con la especificación de servlet V3, como Tomcat, la solución no lo es). Filtrar la URL de respuesta se siente como un truco, porque debe cambiar un comportamiento predeterminado. Pero todo depende de lo que necesite y quiera lograr.

En Tomcat 7 o cualquier servidor de Servlet Specification V3, puede deshabilitar JSessionID en URL agregando seguimiento a la web.xml de su aplicación

<session-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

Aquí hay una solución desagradable en el sabor de un Filter para que nunca verá el JSesionID en URL cada vez que el cliente admite 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 /* o cualquier patrón de URL que requiera gestión de sesiones.

Si tiene una página de envoltura común que usan todas las páginas (para mí, era común. session="false" para usted <%@ 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 ... establecer el valor de c:url a una variable y uso c:out escapeXml="false" Para emitir 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]

Desafortunadamente, la única forma en que he encontrado alrededor de esto es agregar un filtro a su aplicación que despojará el parámetro JSesionID. Es particularmente molesto si está creando un sitio web público y desea que los motores de ESECH indexen sus páginas.

No creo que Tomcat (si eso es lo que está usando) se puede configurar para no agregar esto a su URL. Sin embargo, no puedo decir sobre los otros servidores.

Sin embargo, tenga en cuenta que si crea el filtro y luego necesita administración de sesión y el usuario tiene cookies desactivadas, se encontrará con problemas.

Una solución no es usar <c:url>, pero para usar ${request.contextPath}/path

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top