Question

J'ai un bug étrange: lorsque 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 F5 ou que je rafraîchis la page de toutes les autres manières, tout ce qui est disparu et que tout fonctionne bien jusqu'à ce que je ferme mon navigateur (et tous les onglets doivent également être fermés). Quand je l'ouvre à nouveau, je vois cet étrange paramètre jSessionID.

J'utilise JSTL <c:url..> Tag pour créer toutes les URL.

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

Était-ce utile?

La solution

Ce n'est pas un bug, c'est par conception. Lorsqu'une nouvelle session est créée, le serveur ne sait pas 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 le 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 utiliser explicitement les cookies, mais vous avez implicitement une session, et le conteneur doit suivre cette session.

Autres conseils

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

Dans votre question, le JSessionID est annexé en tant que paramètre, ce qui n'est pas le cas.
Utilisant
<c:url value="/"/>
Génera quelque chose comme ce qui suit: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
Alors en utilisant
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
générera
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, donc votre serveur ne peut pas trouver la ressource disponible.

La meilleure solution de contournement que j'ai trouvée est de utilisation ${pageContext.request.contextPath} à la place de <c:url value="/"/>. Donc, dans l'exemple précédent, vous auriez
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
qui générera
/some/stylesheets/style.css.

Cette solution est conteneur indépendant (Alors que le contenant conforme au servlet V3 - comme la solution Tomcat - ne l'est pas). Le filtrage de l'URL de réponse ressemble à un piratage, 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.

Sur Tomcat 7 ou tout serveur de servlet V3 COMPLIANT Server, vous pouvez désactiver JSessionID dans URL en ajoutant le suivi au web.xml de votre application

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

Voici une solution de contournement désagréable dans la saveur d'un Filter afin que vous ne verrez jamais le JSessionID dans 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);
}

Maptez-le sur /* ou quel que soit le modèle d'URL qui nécessite une gestion de session.

Si vous avez une page de wrapper commune que toutes les pages utilisent (pour moi c'était commun.inc) Vous pouvez ajouter session="false" à ton <%@ 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éfinir la valeur de c:url à une variable et utiliser c:out escapeXml="false" Pour sortir la variable et cela supprimera le SessionID.

Exemple:

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

Alternativement, vous pouvez l'ajouter à votre configuration Apache pour tronquer le sessionID.

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

Malheureusement, la seule façon dont j'ai trouvé ceci 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 souhaitez 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 cependant pas dire pour les autres serveurs.

Cependant, notez que si vous créez le filtre et que vous avez ensuite besoin d'une gestion de session et que l'utilisateur a des cookies désactivés, vous rencontrerez des problèmes.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top