jsessionid se produit dans toutes les URL générées par la balise jstl

J'ai un bug étrange: quand j'ouvre la page pour la première fois dans un navigateur, Toutes les références ont un paramètre jsessionid (comme <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

Lorsque j'appuie sur F5 ou actualise la page par d'autres moyens, tout ce qui est disparu et tout fonctionne bien jusqu'à ce que je ferme mon navigateur (et tous les onglets doivent être fermés aussi). Quand je l'ouvre à nouveau, je vois cet étrange paramètre jsessionid.

J'utilise la balise jstl <c:url..> pour créer toutes les URL.

J'ai lu il y a quelque temps que jsessionid est un alternative aux cookies si les cookies sont désactivés, mais les cookies sont activés et je n'utilise pas de cookies.

27
demandé sur Cœur 2009-06-25 23:07:12

7 réponses

Ce n'est pas un bug, c'est par conception. Lorsqu'une nouvelle session est créée, le serveur n'est pas sûr si le client prend en charge les cookies ou non, et il génère donc un cookie ainsi que le jsessionid sur L'URL. Lorsque le client revient la deuxième fois et présente le cookie, le serveur sait que jsessionid n'est pas nécessaire et le laisse tomber pour le reste de la session. Si le client revient sans cookie, le serveur doit continuer à utiliser la réécriture jsessionid.

Vous ne pouvez pas explicitement utilisez des cookies, mais vous avez implicitement une session, et le conteneur doit suivre cette session.

35
répondu skaffman 2009-06-25 19:09:26

Comme expliqué dans la réponse de skaffman, ce n'est pas un bug. C'est un comportement attendu.

Dans votre question, jsessionid est ajouté en tant que paramètre, ce qui n'est pas le cas.
À l'aide de
<c:url value="/"/>
va générer quelque chose comme ce qui suit: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
Donc, en utilisant
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
va générer
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, de sorte que votre serveur ne peut pas trouver la ressource disponible.

La meilleure solution que j'ai trouvée est de utiliser ${pageContext.request.contextPath} au lieu de <c:url value="/"/>. Ainsi, dans l'exemple précédent, vous auriez
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
que va générer
/some/stylesheets/style.css.

Cette solution est indépendante du conteneur (alors que la solution Tomcat compatible avec la spécification de servlet v3 ne l'est pas). Le filtrage de l'url de réponse ressemble à un hack, car vous devez modifier un comportement par défaut. Mais tout dépend de ce dont vous avez besoin et que vous voulez réaliser.

25
répondu despot 2017-05-23 10:31:12

Sur Tomcat 7 ou tout serveur compatible servlet specification v3, vous pouvez désactiver jsessionid dans L'URL en ajoutant suivant sur le web.xml de votre application

<session-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>
13
répondu maneesh 2012-02-08 17:13:46

Voici une mauvaise solution de contournement dans la saveur d'un Filter de sorte que vous ne verrez jamais le jsessionid dans L'URL chaque fois que le client prend en charge les 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);
}

Mappez-le sur /* ou n'importe quel modèle D'URL qui nécessite une gestion de session.

5
répondu BalusC 2010-10-25 22:46:38

Si vous avez une page d'emballage commune que toutes les pages utilisent (pour moi, c'était commun.Inc) vous pouvez ajouter session="false" à votre <%@ page pour supprimer le sessionid.

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

Alternativement.. définissez la valeur de c:url sur une variable et utilisez c:out escapeXml="false" pour afficher la variable et cela supprimera le sessionid.

Exemple:

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

Vous pouvez également ajouter ceci à votre configuration Apache pour tronquer le sessionid.

ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]
2
répondu davidcondrey 2015-02-17 21:26:25

Malheureusement, la seule façon que j'ai trouvée est d'ajouter un filtre à votre application qui supprimera le paramètre jsessionid. C'est particulièrement ennuyeux si vous créez un site web public et que vous voulez que les moteurs de recherche indexent vos pages.

Je ne crois pas que tomcat (si c'est ce que vous utilisez) puisse être configuré pour ne pas l'ajouter à votre url. Je ne peux pas dire pour les autres serveurs cependant.

Cependant, notez que si vous créez le filtre et que vous gestion des sessions et l'Utilisateur a des cookies désactivés, vous rencontrerez des problèmes.

0
répondu Vincent Ramdhanie 2009-06-25 19:32:50

Une solution de contournement n'est pas d'utiliser <c:url>, mais d'utiliser ${request.contextPath}/path

0
répondu Bozho 2010-10-25 19:33:15