Domanda

Ho uno strano bug: quando apro la pagina per la prima volta in alcuni browser tutti i riferimenti hanno un parametro JSessionid (come <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

Quando premo F5 o aggiorno la pagina in qualsiasi altro modo per tutta quella roba è scomparsa e tutto funziona bene fino a quando chiudo il mio browser (e anche tutte le schede dovrebbero essere chiuse). Quando lo apro di nuovo vedo questo strano parametro JSessionid.

Uso JSTL <c:url..> Tag per la creazione di tutti gli URL.

Ho letto qualche tempo fa che JSessionid è un'alternativa ai cookie se i cookie sono disabilitati, ma i cookie sono abilitati e in realtà non uso i cookie.

È stato utile?

Soluzione

Questo non è un bug, è di progettazione. Quando viene creata una nuova sessione, il server non è sicuro che il client supporti i cookie o meno, e quindi genera un cookie e JSessionid sull'URL. Quando il client torna la seconda volta e presenta il cookie, il server sa che JSessionid non è necessario e lo lascia cadere per il resto della sessione. Se il client torna senza cookie, il server deve continuare a utilizzare la riscrittura di JSessionid.

Non è possibile utilizzare esplicitamente i cookie, ma hai implicitamente una sessione e il contenitore deve tenere traccia di quella sessione.

Altri suggerimenti

Come spiegato in Risposta di Skaffman, Non è un bug. È un comportamento previsto.

Nella tua domanda il JSessionid è aggiunto come parametro, il che non è il caso.
Usando
<c:url value="/"/>
genererà qualcosa come i seguenti: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
Quindi usando
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
genererà
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, quindi il tuo server non riesce a trovare la risorsa disponibile.

La migliore soluzione che ho trovato è uso ${pageContext.request.contextPath} invece di <c:url value="/"/>. Quindi nell'esempio precedente, lo avresti
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
che genererà
/some/stylesheets/style.css.

Questa soluzione è Container indipendente (mentre il contenitore conforme a Servlet Specifiche V3 - come Tomcat - la soluzione non lo è). Filtrando l'URL di risposta sembra un hack, perché è necessario modificare un comportamento predefinito. Ma tutto dipende da ciò di cui hai bisogno e vuoi ottenere.

Su Tomcat 7 o qualsiasi server Servlet Specifica V3 è possibile disabilitare JSessionID in URL aggiungendo seguenti a Web.xml dell'applicazione

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

Ecco una brutta soluzione al sapore di a Filter In modo che non vedrai mai il JSessionid in URL ogni volta che il cliente supporta i cookie.

@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);
}

Mappalo /* o qualunque sia il modello URL che richiede la gestione della sessione.

Se hai una pagina wrapper comune che tutte le pagine usano (per me era comune.inc) puoi aggiungere session="false" alla tua <%@ page Per rimuovere il sessionid.

Esempio 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 }" />

In alternativa .. imposta il valore di c:url a una variabile e usa c:out escapeXml="false" Per produrre la variabile e questo rimuoverà il session.

Esempio:

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

In alternativa, puoi aggiungere questo alla configurazione Apache per troncare il session.

ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]

Sfortunatamente l'unico modo in cui ho trovato intorno a questo è aggiungere un filtro alla tua applicazione che toglie il parametro JSessionid. È particolarmente fastidioso se stai creando un sito Web pubblico e vuoi che i motori di ricerca indicizzano le tue pagine.

Non credo che Tomcat (se è quello che stai usando) possa essere configurato per non aggiungere questo al tuo URL. Non posso dire per gli altri server però.

Tuttavia, tieni presente che se si crea il filtro e si richiede quindi la gestione della sessione e l'utente ha i cookie disattivati, si imbatte in problemi.

Una soluzione alternativa non è da usare <c:url>, ma usare ${request.contextPath}/path

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top