2016-04-15 23 views
1

Ich laufe Mojarra 2.2.0. Wann erstellt JSF eine Sitzung und was wird in eine Sitzungszuordnung eingefügt?

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
    </context-param> 

Die Managed Bean Action-Methode ist

public void action() { 
     HttpSession session = (HttpSession) FacesContext.getCurrentInstance() 
       .getExternalContext().getSession(false); 
     System.out.println(session.getId()); // not null for stateful views 
    } 

Für stateless Ansichten session.getId()NPE

Für Ansichten werfen die nicht stateless- ist eine GET-Anfrage Entlassung, gibt es JSESSIONID=340041C96D5AA446D761C3602F54A76D

Ich lese es here that-

Für Client-Seite Sparzustand Mechanismus, JSF wird die Sitzung nicht schaffen und den Ansichtszustand in einem verborgenen Eingabefeld mit dem Namen javax.faces.ViewState in Form speichern, wann immer notwendig.

Ferner es hier erwähnt that

JSF wird in der Tat die Sitzung automatisch erstellt, weil der JSF Ansichtszustand hat dort gespeichert werden. Wenn Sie den JSF Sparzustand Methode Client anstelle des Servers gesetzt ist, dann wird es nicht in der Sitzung gespeichert werden und somit braucht keine Sitzung erstellt werden

ich glaube, die über der Linie eine Quelle für Schwierigkeiten ist für mich.

Wenn Sie den JSF Zustand sparende Methode zum Client anstelle von Server festgelegt, dann wird es nicht in der Sitzung gespeichert werden // EINGE VOLL

und

daher keine Sitzung muss erstellt werden. // Das verwirrt, weil für clientseitige Speichermechanismus eine Sitzungs-ID vom Servlet-Container & generiert wird, daher gibt es eine Sitzung, die der -Anforderung zugeordnet ist.

In Bezug auf die Diskussion, die ich mit BalusC in diesem question hatte, habe ich ein HttpSessionListener-

@WebListener 
public class MyHttpSessionListener implements HttpSessionListener { 

    public void sessionCreated(HttpSessionEvent event) { 
     Thread.dumpStack(); 
    } 

    public void sessionDestroyed(HttpSessionEvent event) { 

    } 

} 

Anbei Screenshots anzeigen (diese 2 Screenshots sind für Version 2.0.3, da muss ein alter Fehler, aufgrund derer gewesen, wurde die Sitzung) erstellt bekommen -

enter image description here

enter image description here

Libraby (Mojarra 2.2.0) - enter image description here

+0

@BalusC: Eclipse IDE automatisch für mich heruntergeladen. Ich befestige auch den Screenshot. –

+0

@BalusC: Sorry für diesen dummen Fehler. Ich dachte, das Entfernen der Bibliothek 2.0.3 aus dem Buildpath würde sie vollständig entfernen. Für Mojarra 2.2.0 wird jetzt derselbe HttpSession Listener nicht aufgerufen. Irgendwelche Vorschläge? –

+0

@BalusC: Ahh, ich verstehe. Jetzt hab ich es verstanden. Ich denke, die Quelle für dieses ganze Problem war die Versionsnummer. –

Antwort

3

Wann JSF erzeugt eine Session

Eaiest Weg, dies zu Naildown ein HttpSessionListener erstellen, eine Debug-Haltepunkt auf sessionCreated() Methode setzen und Inspizieren des Call-Stack, der benötigt Holen Sie sich die Sitzung zum ersten Mal (und muss sie daher implizit erstellen).

Im folgenden Beispiel sehen Sie eine Kette von getSession() Aufrufen in der Aufrufliste. Sie werden sehen, dass die Methode FaceletViewHandlingStrategy.renderView() diejenige ist, die sie zum ersten Mal aufruft.

enter image description here

Nachdem Sie auf FaceletViewHandlingStrategy.renderView() Linie in Debuggers Call-Stack klicken, werden Sie den Quellcode erhalten in (Maven wird automatisch Quellcode laden, sonst müssen Sie es manuell anhängen).

enter image description here

Sie sehen, wenn Serverseite Zustand Speicher aktiviert ist und die Aussicht ist zu machen, nicht transient (stateless), dann JSF wird implizit die Sitzung erstellen, nur um sicherzustellen, dass sie rechtzeitig, um erstellt werden zu sparen die Ansicht (wenn die Sitzung später erstellt wurde, z. B. während der Renderantwortphase, riskieren Sie andernfalls Ausnahmen wie diese Adding <h:form> causes java.lang.IllegalStateException: Cannot create a session after the response has been committed).

Sie werden im Quelltext auch sofort sehen, dass wenn die State-Saving-Methode auf Client gesetzt ist, oder wenn die View zustandslos ist wie in <f:view transient="true">, JSF die Sitzung nicht mehr implizit erstellt. Ältere JSF-Versionen können das so tun, wie Sie es sich vorgestellt haben, aber dies ist als Fehler zu betrachten und sollte in einer neueren Version behoben werden.

Wenn Sie Staatenlosigkeit sicherstellen und versehentliche/unvorhergesehene Sitzungserstellung vermeiden möchten, dann könnten Sie einfach throw new IllegalStateException() innerhalb sessionCreated() Methode. Wenn dies passiert, müssen Sie nur im Call-Stack nachsehen, wer für das Erstellen der Sitzung zuständig ist und dann den Code reparieren/ändern, um dies nicht mehr zu tun.


was bedeutet es in einer Sitzung Karte setzt?

Unter den Abdeckungen, ExternalContext#getSessionMap() Delegierten HttpSession#setAttribute()/getAttribute()/removeAttribute(). Sie können diese Methoden mit einem HttpSessionAttributeListener hören.

Im folgenden Beispiel sehen Sie, dass ViewScopeContextManager.getContextMap() Zeile SessionMap#put() Methode aufruft, um etwas in die Sitzungszuordnung zu setzen. Wenn Sie das Argument event öffnen, sehen Sie den Sitzungsattributnamen und -wert, der com.sun.faces.application.view.activeViewContexts bzw. ein leeres ConcurrentHashMap ist.

enter image description here

der Tat, ich war ein @Named @ViewScoped verwendet, die von einem Wertausdruck auf der bestimmten Seite (sehen Sie EL-Resolver und Weld Resolver weiter unten im Call-Stack) verwiesen wurde.Wenn Sie im Callstack auf ViewScopeContextManager.getContextMap() klicken, sehen Sie, dass nur eine Map im Sitzungsumfang vorbereitet wurde, um View-Bereichsbeans zu speichern.

enter image description here

Das ist nur ein Beispiel ist. Es gibt mehr Dinge, die in der Sitzung gespeichert werden könnten. Einen Debugger auf diese Weise zu verwenden und den zugehörigen Quellcode zu inspizieren wird viel über die Warum.