J'ai un bug étrange: lorsque j'ouvre la page pour la première fois dans certains navigateurs, toutes les références ont le paramètre jsessionid (comme <a href="/articles?name=art&jsessionid=5as45df4as5df"..>
).
Lorsque j'appuie sur F5 ou que j'actualise la page par tout autre moyen, tout cela disparaît et 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.
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 pour la deuxième fois et présente le cookie, le serveur sait que le jsessionid n'est pas nécessaire et le supprime 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.
Comme expliqué dans réponse de skaffman , ce n'est pas un bug. C'est un comportement attendu.
Dans votre question, le jsessionid est ajouté en tant que paramètre, ce qui n'est pas le cas.
En utilisant<c:url value="/"/>
générera 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"/>
générera/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, votre serveur ne peut donc pas trouver la ressource disponible.
La meilleure solution de contournement que j'ai trouvée est d'utiliser ${pageContext.request.contextPath}
au lieu 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 indépendante du conteneur (alors que la solution de conteneur conforme à la spécification de servlet v3 - comme Tomcat - ne l'est pas). Filtrer l'url de réponse ressemble à un hack, car vous devez changer un comportement par défaut. Mais tout dépend de ce dont vous avez besoin et de ce que vous voulez réaliser.
Sur Tomcat 7 ou tout serveur conforme à la spécification de servlet v3, vous pouvez désactiver jsessionid dans l'URL en ajoutant ce qui suit au fichier 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 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 tout autre modèle d'URL nécessitant une gestion de session.
Si vous avez une page wrapper commune que toutes les pages utilisent (pour moi c'était common.inc), vous pouvez ajouter session="false"
à ton <%@ page
pour supprimer l'identifiant de session.
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 }" />
Sinon .. définissez la valeur de c:url
à une variable et utilisez c:out escapeXml="false"
pour afficher la variable et cela supprimera l'identifiant de session.
Exemple:
<c:url value=${url} var="image"/>
<c:out var=${image} escapeXml="false"/>
Vous pouvez également l'ajouter à votre configuration Apache pour tronquer l'identifiant de session.
ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]
Malheureusement, le seul moyen que j'ai trouvé à ce sujet 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 avez besoin d'une gestion de session et que l'utilisateur a désactivé les cookies, vous rencontrerez des problèmes.
Une solution de contournement consiste à ne pas utiliser <c:url>
, mais pour utiliser ${request.contextPath}/path