2009-06-25 18 views
25

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"..>).jsessionid se produce en todas las direcciones URL generadas por jstl <c:url..> etiqueta

Cuando presiono F5 o actualizo 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 estar cerradas). Cuando lo vuelvo a abrir veo este extraño parámetro jsessionid.

Utilizo la etiqueta jstl <c:url..> para crear todas las URL.

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

Respuesta

34

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.

+0

es bueno, pero todo mi CSS parece "link rel =" .. "href ="/mysite/css/styles.css? Jsessionid = as2dfs4df ". ¿Puedo desactivar este comportamiento predeterminado o sería una mala práctica y Debería arreglar mi css-cargando? – Roman

+2

Eso va a depender de qué contenedor está ejecutando en – skaffman

0

Desafortunadamente, la única forma en que he encontrado esto es agregar un filtro a su aplicación que quitará 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 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.

+0

Es interesante que su ejemplo tiene jsessionid como un parámetro en la URL. No he visto el antes. Tomcat lo pone como un postfix a la URL (ej. my/path; jsessionid = ... & x = y), que pensé que era lo que requería la especificación de servlet. – skaffman

+0

En realidad cometí un error, no es un parámetro, pero olvidé exactamente el formato en ese momento – Roman

+0

se puede utilizar Tomcat 7. Tomcat 6.0.30 tendrá esta función. – Wes

0

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

+1

Solo para aclarar esto, debería ser '$ {pageContext.request.contextPath}'. – delfuego

4

He aquí una solución desagradable sabor de un Filter de modo que usted nunca verá el jsessionid en URL siempre que el cliente soporta 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); 
} 

Mapa en /* o cualquier patrón de URL que requieren la administración de sesiones.

+0

Hola BalusC, gracias por el ¡Respuesta! No lo hice o desarrollo web actualmente, pero probaré su solución en uno de mis proyectos anteriores que tenía este problema. ¿Podría explicar un poco (o dar un enlace correspondiente) el concepto de URL codificada/no codificada? ¿Por qué es la materia? La otra cosa aquí que me falta conocimiento para entenderlo es el atributo "verificado" para la sesión. ¿Quién y cuándo se establece normalmente? – Roman

+0

Skaffman ha respondido a la necesidad de jsessionid en URL. El atributo 'verificado' está ahí para evitar que el filtro se ejecute en un bucle infinito una vez que se haya verificado el soporte de las cookies. Puedes cambiarle el nombre a otra cosa. – BalusC

13

en Tomcat 7 v3 o cualquier servidor compatible con la especificación servlet puede desactivar jsessionid en la URL mediante la adición siguiente al web.xml de la aplicación

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

Esto funcionó para mí en tomcat 7. – Mukus

+5

'c: url' todavía puede hacer que' jsessionid' se anexe, incluso con esta configuración. tomcat7/servlet3 – beerbajay

+0

Funciona para mí, estoy usando embarcadero incrustado. – Junjie

23

Como se explica en skaffman's answer, no es un error. Es un comportamiento esperado.

En su pregunta, el jsessionid se anexa como parámetro, que no es el caso.
Usando
<c:url value="/"/>
generará algo como lo siguiente: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
Así, utilizando
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
generará
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, por lo que el servidor no puede encontrar el recurso disponible.

La mejor solución que encontré es use ${pageContext.request.contextPath} en lugar de <c:url value="/"/>. Por lo tanto, en el ejemplo anterior, tendría
<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 que cumple con la especificación de vèlet v3, como Tomcat, no). 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.

2

Si tiene una página de contenedor 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 .. establecer el valor de c:url a una variable y utilizar c:out escapeXml="false" a la salida de la variable y se eliminará el sessionid.

Ejemplo:

<c:url value=${url} var="image"/> 
<c:out var=${image} escapeXml="false"/> 

Alternativamente, se puede añadir 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] 
Cuestiones relacionadas