+ Antworten
Ergebnis 1 bis 8 von 8

Thema: Facelets --- LifecycleRätsel

  1. #1
    User int Themenstarter

    Registriert seit
    15.12.2013
    Fachbeiträge
    39
    Genannt
    1 Post(s)
    Hi!

    Ich habe hier eine neue JSF2.2App@Tomcat8.0. Gebaut mit Netbeans 8.1

    Das Problem kurz erklärt:
    Template mit Inserts für Left und Content.

    Left: Enthält ein Formular, welches an eine Bean im SessionScope gebunden ist. Ein CommandButton gebunden an eine Action in der nichts passiert ausser return ""

    Content: Ein OutputText, gebunden an eine RequestScopedBean, welche die o.g. SessionScopedBean, als ManagedProperty enthält. Es soll ein Property der SessionScopedBean angezeigt werden. Im PostConstruct der RequestScopedBean wir ein Property gesetzt, wenn der Eingegebene Text länger, als 10 ist. Wenn dieses Property true ist, dann soll der OutputText nicht gerendert werden.

    Das Problem:
    Eigentlich sollte nach betätigen des CommandButton die Action der SessionScopedBean ausgeführt werden und erst dann die PostConstruct der RequestScopedBean.

    Im Fall von <hutputText value="#{requestScopedBean.sessionBean.userName}" /> läuft das so korrekt ab.

    Sobald <hutputText value="#{requestScopedBean.sessionBean.userName}" rendered="#{requestScopedBean.showUserName2}" /> in der XHTML steht, dann wird die Reihenfolge umgedreht, sodass erst die PostConstruct und erst dann die Action aufgerufen wird. Das ist doof, da die Eingabe früher ausgewertet wird, als sie in der SessionScopedBean aktualisiert wurde.

    Wo liegt das Problem? bzw. wie kann ich erzwingen, dass die Action der SessionScopedBean zuerst aufgerufen wird.


    Der Code, als zip:
    Jsf2.2Test.zip

    Die wichtigsten Sachen gekürzt hier
    Content
    XML Code:
    1. <ui:composition template="./newTemplate.xhtml">
    2.             <ui:define name="content">
    3.                 Username1: <h:outputText value="#{requestScopedBean.sessionBean.userName}" /><br/>
    4.                 Username2: <h:outputText value="#{requestScopedBean.sessionBean.userName}" rendered="#{requestScopedBean.showUserName2}" />
    5.             </ui:define>
    6.         </ui:composition>

    requestScopedBean
    Java Code:
    1.     public void init(){
    2.         if(sessionBean.getUserName().length() > 10){
    3.             showUserName2 = false;
    4.         }else{
    5.             showUserName2 = true;
    6.         }
    7.     }

    sessionScopedBean
    Java Code:
    1. @ManagedBean
    2. @SessionScoped
    3. //@ApplicationScoped
    4. public class SessionScopedBean {
    5.  
    6.     private String userName = "";
    7.    
    8.     public String action(){
    9.  
    10.        
    11.         return "";
    12.     }
    13.    
    14.  
    15.     public String getUserName() {
    16.         return userName;
    17.     }
    18.  
    19.     public void setUserName(String userName) {
    20.         this.userName = userName;
    21.     }
    22.    
    23. }
    Geändert von dpo (24.07.2016 um 09:45 Uhr)

  2. #2
    Projekt-Moderator Butterfaces Halbes Megabyte Avatar von Sym
    Registriert seit
    31.07.2013
    Fachbeiträge
    577
    Genannt
    28 Post(s)
    Hallo,

    Richtig wäre: Es wird zunächst PostConstruct ausgeführt und dann die Action. Warum das in Deinem einen Fall anders ist, klingt nach einem Fehler.

    Raten würde ich Dir auf CDI zu wechseln, da die Standard-JSF-Annotationen nur für den Übergang zu CDI gedacht waren. Als JSF2 auf den Markt kam, war CDI noch nicht so weit, deshalb gab es ein eigenes DI.

    Zu Deinem aktuellen Problem: Kannst Du das, was Du im PostConstruct machst, nicht einfach in der Action-Methode tun?
    www.butterfaces.org = JSF 2 + Bootstrap + JQuery = awesome
    https://github.com/larmic

  3. #3
    User int Themenstarter

    Registriert seit
    15.12.2013
    Fachbeiträge
    39
    Genannt
    1 Post(s)
    Danke!

    Zitat Zitat von Sym Beitrag anzeigen
    Richtig wäre: Es wird zunächst PostConstruct ausgeführt und dann die Action. Warum das in Deinem einen Fall anders ist, klingt nach einem Fehler.
    Das ist natürlich super, denn default ist es bei mir genau umgekehrt. Erst wenn rendered in einem JSF-Tag steht, dann ist es, wie Du es schreibst.

    Zitat Zitat von Sym Beitrag anzeigen
    Zu Deinem aktuellen Problem: Kannst Du das, was Du im PostConstruct machst, nicht einfach in der Action-Methode tun?
    Die Postconstruct existiert in diesem Beispiel nur, um an geeigneter Stelle einen BreakPoint setzten zu können, damit man den Spaß untersuchen kann. Wichtig ist in dem Fall nur das rendered funktioniert, wenn in der SessionScopedBean etwas besonderes drinsteht. Natürlich könnte ich das mit JavaScript erledigen.

    Ich hoffe doch nicht, dass es ein JSF-Bug ist, denn ich qualvoll umgehen muß.

    Zitat Zitat von Sym Beitrag anzeigen
    Raten würde ich Dir auf CDI zu wechseln, da die Standard-JSF-Annotationen nur für den Übergang zu CDI gedacht waren.
    Das scheint es auf dem Tomcat nicht zu geben.
    Geändert von dpo (24.07.2016 um 11:15 Uhr)

  4. #4
    Projekt-Moderator Butterfaces Halbes Megabyte Avatar von Sym
    Registriert seit
    31.07.2013
    Fachbeiträge
    577
    Genannt
    28 Post(s)
    CDI geht auch mit dem Tomcat. Es muss nur entsprechend eingerichtet werden. JSF gehört ja auch nicht zum Default-Tomcat-Stack

    Aber debuggen kannst Du doch auch die Actionmethode. Da kannst Du die Sessionbean ja direkt auslesen. Es werden erst die Felder submitted und dann die Action aufgerufen. Oder hast Du damit Probleme?
    www.butterfaces.org = JSF 2 + Bootstrap + JQuery = awesome
    https://github.com/larmic

  5. #5
    User int Themenstarter

    Registriert seit
    15.12.2013
    Fachbeiträge
    39
    Genannt
    1 Post(s)
    Zitat Zitat von Sym Beitrag anzeigen
    ... Aber debuggen kannst Du doch auch die Actionmethode. Da kannst Du die Sessionbean ja direkt auslesen. Es werden erst die Felder submitted und dann die Action aufgerufen. Oder hast Du damit Probleme?
    Ja klar ... Ohne rendered werden die Methoden in der Reihenfolge aufgerufen aufgerufen
    1 SessionScopedBean Action mit den submiteten Feldern
    2 RequestScopedBean Postconstruct. Die felder bekomme ich von der SessionScopedBean
    Das passt

    Sobald ein rendered in der XHTML steht dann ist die Reihenfolge so
    1 RequestScopedBean PostConstruct. Die Daten der Felder werden jetzt gebraucht, aber wurden noch nicht submittet
    2 SessionScopedBean Action und erst jetzt werden die Daten submittet
    Das passt nicht

  6. #6
    User int Themenstarter

    Registriert seit
    15.12.2013
    Fachbeiträge
    39
    Genannt
    1 Post(s)
    Wenn ich den Button drücke der SessionScopedBean.Action() auslöst, welche Methode soll als erstes laufen?

    - SessionScopedBean.Action
    oder
    - RequestScopedBean.Postconstruct

  7. #7
    User Viertel Megabyte Avatar von inv_zim
    Registriert seit
    31.07.2013
    Ort
    Rhein-Main Gebiet
    Fachbeiträge
    372
    Genannt
    31 Post(s)
    Hi,

    PostConstruct sollte meines Wissens nach direkt nach dem Konstruktor aufgerufen werden, damit also vor der Action.
    I am obsessed with the ancient science of "puzzle-ometry". I have discovered that within puzzles lies the secret of human intelligence, that which separates us from the common beast.

  8. #8
    User int Themenstarter

    Registriert seit
    15.12.2013
    Fachbeiträge
    39
    Genannt
    1 Post(s)
    Zitat Zitat von inv_zim Beitrag anzeigen
    PostConstruct sollte meines Wissens nach direkt nach dem Konstruktor aufgerufen werden, damit also vor der Action.
    Das schon, aber in dem Fall haben wir 2 Beans und die SessionScopedBean überlebt einige PostConstructs der RequestScopedBean.

+ Antworten Thema als "gelöst" markieren

Direkt antworten Direkt antworten

Wie lautet das letzte Wort am Ende dieser Webseite?

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •