2009-06-25 3 views
25

Ich habe einige seltsame Fehler: Wenn ich Seite erstmals in einem Browser öffnen, hat alle Referenzen jsessionid Parameter (wie <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).jsessionid ist in allen URLs aufgetreten, die von jstl <c:url..> generiert werden Tag

Wenn ich F5 drücke oder die Seite auf andere Weise aktualisiere, sind all diese Dinge verschwunden und alles funktioniert gut, bis ich meinen Browser schließe (und alle Tabs sollten ebenfalls geschlossen werden). Wenn ich es wieder öffne, sehe ich diesen seltsamen jsessionid-Parameter.

Ich verwende jstl <c:url..> Tag zum Erstellen aller URLs.

Ich habe vor einiger Zeit gelesen, dass jsessionid eine Alternative zu Cookies ist, wenn Cookies deaktiviert sind, aber Cookies aktiviert sind und ich tatsächlich keine Cookies verwende.

Antwort

34

Dies ist kein Fehler, es ist von Entwurf. Wenn eine neue Sitzung erstellt wird, ist der Server nicht sicher, ob der Client Cookies unterstützt oder nicht und generiert daher einen Cookie sowie die jsessionid in der URL. Wenn der Client das zweite Mal zurückkehrt und den Cookie anzeigt, weiß der Server, dass die Jsessionid nicht erforderlich ist, und löscht sie für den Rest der Sitzung. Wenn der Client ohne Cookie zurückkommt, muss der Server weiterhin jsessionid rewriting verwenden.

Sie können nicht explizit Cookies verwenden, aber Sie haben implizit eine Sitzung und der Container muss diese Sitzung verfolgen.

+0

das ist nett, aber alle meine CSS aussehen wie "Link rel =" .. "href ="/mysite/css/styles.css? Jsessionid = as2dfs4df ". Kann ich dieses Standardverhalten ausschalten oder es wäre eine schlechte Praxis und ich sollte meine CSS-Laden zu beheben? – Roman

+2

, an dem Behälter abhängig sein wird sind Sie in – skaffman

0

Leider habe ich nur einen Filter zu Ihrer Anwendung hinzugefügt, der den jsessionid-Parameter entfernt. Besonders nervig ist es, wenn Sie eine öffentliche Website erstellen und die Suchmaschinen Ihre Seiten indexieren lassen wollen.

Ich glaube nicht, dass Tomcat (wenn das ist, was Sie verwenden) kann konfiguriert werden, um dies nicht zu Ihrer URL hinzuzufügen. Ich kann jedoch nicht für die anderen Server sagen.

Wenn Sie jedoch den Filter erstellen und dann die Sitzungsverwaltung benötigen und der Benutzer die Cookies deaktiviert hat, treten Probleme auf.

+0

läuft es ist interessant, dass sein Beispiel als Parameter in der URL jsessionid hat. ich vorher nicht gesehen haben. Tomcat es ausdrückt in als ein Postfix zur URL (zB mein/pfad; jsessionid = ... & x = y), was ich für die Servlet-Spezifikation hielt – skaffman

+0

Eigentlich habe ich einen Fehler gemacht, es ist kein Parameter, aber ich habe das genaue Format vergessen In diesem Moment kann – Roman

+0

Tomcat 7 verwendet werden, Tomcat 6.0.30 wird diese Funktion haben – Wes

0

Eine Abhilfe ist nicht <c:url> zu verwenden, aber ${request.contextPath}/path

+1

Nur um dies zu verdeutlichen - es sollte '$ {pageContext.request.contextPath}'. – delfuego

4

Hier ist eine unangenehme Abhilfe im Geschmack eines Filter zu verwenden, so dass Sie nie die jsessionid in URL sehen, wenn der Client Cookies unterstützt.

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

Karte auf /* oder was auch immer URL-Muster, das Session-Management erfordern.

+0

Hallo BalusC, danke für die Antwort, ich nicht o Web-Entwicklung derzeit, aber ich werde versuchen, Ihre Lösung für eines meiner alten Projekte, die dieses Problem hatten. Können Sie das Konzept der codierten/nicht codierten URL ein wenig erläutern (oder einen entsprechenden Link angeben)? Warum ist es wichtig? Die andere Sache hier, für die ich kein Wissen habe, um es zu verstehen, ist das "verifizierte" Attribut für die Sitzung. Wer und wann hat es normalerweise festgelegt? – Roman

+0

Skaffman hat auf die Notwendigkeit für jsessionid in URL geantwortet. Das verifizierte Attribut ist nur dazu da, um zu verhindern, dass der Filter in einer Endlosschleife läuft, sobald die Cookie-Unterstützung verifiziert wurde. Sie können es in etwas anderes umbenennen. – BalusC

13

auf Tomcat 7 oder ein Servlet-Spezifikation v3 kompatibeler Server Sie jsessionid in URL durch Zugabe von folgenden web.xml Ihrer Anwendung

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

Das hat bei mir in Tomcat 7 funktioniert. – Mukus

+5

'c: url' kann immer noch dazu führen, dass' jsessionid' angehängt wird, auch mit dieser Einstellung. tomcat7/servlet3 – beerbajay

+0

Funktioniert für mich, ich verwende Embedded Jetty. – Junjie

23

Wie in skaffman's answer, seinen keinen Fehler deaktivieren. Es ist ein erwartetes Verhalten.

In Ihrer Frage wird die jsessionid als Parameter angehängt, was nicht der Fall ist.
Mit
<c:url value="/"/>
wird etwas wie das folgende erzeugt: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
So
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
mit
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
generieren, so dass Ihr Server die Ressource zur Verfügung finden.

Die beste Abhilfe, die ich zu Verwendung gefunden ${pageContext.request.contextPath} statt <c:url value="/"/>. Im vorherigen Beispiel hätten Sie
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
, die
/some/stylesheets/style.css generieren.

Diese Lösung ist Container unabhängig (während die Servlet-Spezifikation v3-konform Container - wie Tomcat - Lösung ist nicht). Das Filtern der Antwort-URL fühlt sich an wie ein Hack, da Sie ein Standardverhalten ändern müssen. Aber alles hängt davon ab, was Sie brauchen und erreichen wollen.

2

Wenn Sie haben eine gemeinsame Wrapper-Seite, die alle Seiten verwenden (für mich war es common.inc) Sie session="false" zu Ihrem <%@ page hinzufügen können die sessionid zu entfernen.

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

Alternativ .. den Wert c:url zu einer Variablen gesetzt und verwenden c:out escapeXml="false" die Variable Ausgang und dies wird die sessionid entfernen.

Beispiel:

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

Alternativ können Sie diese zu Ihrer Apache-Konfiguration fügen Sie die sessionid trunkieren.

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