# Kommunikation zwischen JSF Managed Beans



## Deadalus (12. Jan 2010)

Hi,

ich hätte da mal eine Frage. 

Ist es möglich, von einer Instanz eines Managed Bean auf Variablen eines anderen Managed Beans zuzugreifen? 

In meiner Anwendung gibt es mehrere Tabellen. Dabei gibt es eine Haupttabelle. Wird in dieser eine Zeile selektiert füllen sich die anderen Tabellen mit den Verknüpften Daten der Selektion.

Einfaches Beispiel ich selektiere eine Person und sehe in einer anderen Tabelle alle Adressen dieser Person. 

Ich möchte aus Gründen der Übersiucht ungern alle diese Tabellen in einer Managed Bean verwalten. Um die Funktionalität in anderen Beans zu kapseln brauche ich aber Zugriff auf die Variablen.


----------



## Biohazard (12. Jan 2010)

Ich kann dir nicht direkt weiter helfen,
aber über FacesContext ist es irgendwie möglich die Werte aus einem Request wieder auszulesen.
Allerdings habe ich bis jetzt noch nicht herausgefunden, wie ich bestimmte Objekte bzw. Wertigkeiten 
dort wieder rauslesen kann.
Ich sitze also derzeit am selben Problem!

Leider habe ich bisher noch nicht mehr rausgefunden.
Falls du dich auch in diese Richtung schlau machst und eine Lösung findest,
sei so nett und lass es mich wissen ;-)

LG


----------



## MrWhite (12. Jan 2010)

Mit JBOSS Seam könntest du das einfach über Injection und Outjection machen und so eine lose Kopplung wahren. Ähnliches geht wahrscheinlich mit Spring.

Oder du baust einen Controller, der die beiden anderen kapselt und zusammenführt.

Letztendlich kannst du auch einfach ein Objekt in der Session speichern und beim Page-Load auswerten.


----------



## jule37 (12. Jan 2010)

grob aus dem kopf glaube ich, es war so:


```
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("managedBeanName");
```

wenn nicht genau so, dann in diese richtung. lies dir notfalls die javadocs vom FacesContext durch, da findest du es 100pro irgendwo

edit: achja, das bean muss dazu session scope haben, glaub ich


----------



## Biohazard (13. Jan 2010)

Ok,

aber wie genau kommt man dann wieder an die Werte des Beans?
Dieser Aufruf liefert eine Map<String, Object> zurück und ich verstehe die weitere Vorgehensweise nicht ganz. Eine Erklärung wäre super!


----------



## Biohazard (13. Jan 2010)

Jemand hat mich erlöst und mir gezeigt wie es geht 

Hier die Beispiele anhand derer man sich alles ableiten kann :


```
public class MyBean1 {

    // Actions -----------------------------------------------------------------------------------

    // Using RequestMap. NOTE: myBean2 should be request scoped and already created!
    public void action1() {
        MyBean2 myBean2 = (MyBean2) FacesContext.getCurrentInstance().getExternalContext()
            .getRequestMap().get("myBean2");
                            
        // This only works if myBean2 is request scoped and already created.
        if (myBean2 != null) {
            myBean2.getText().setValue("action1");
        }
    }

    // Using SessionMap. NOTE: myBean2 should be session scoped and already created!
    public void action2() {
        MyBean2 myBean2 = (MyBean2) FacesContext.getCurrentInstance().getExternalContext()
            .getSessionMap().get("myBean2");
                            
        // This only works if myBean2 is session scoped and already created.
        if (myBean2 != null) {
            myBean2.getText().setValue("action2");
        }
    }

    // Using ApplicationMap. NOTE: myBean2 should be application scoped and already created!
    public void action3() {
        MyBean2 myBean2 = (MyBean2) FacesContext.getCurrentInstance().getExternalContext()
            .getApplicationMap().get("myBean2");
                            
        // This only works if myBean2 is application scoped and already created.
        if (myBean2 != null) {
            myBean2.getText().setValue("action3");
        }
    }

    // Using VariableResolver. NOTE: this is deprecated since JSF 1.2!
    public void action4() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication()
            .getVariableResolver().resolveVariable(context, "myBean2");

        myBean2.getText().setValue("action4");
    }

    // Using ValueBinding. NOTE: this is deprecated since JSF 1.2!
    public void action5() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication()
            .createValueBinding("#{myBean2}").getValue(context);

        myBean2.getText().setValue("action5");
    }

    // Using ELResolver. NOTE: this is implemented since JSF 1.2!
    public void action6() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getELContext()
            .getELResolver().getValue(context.getELContext(), null, "myBean2");

        myBean2.getText().setValue("action6");
    }

    // Using ValueExpression. NOTE: this is implemented since JSF 1.2!
    public void action7() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication().getExpressionFactory()
            .createValueExpression(context.getELContext(), "#{myBean2}", MyBean2.class)
                .getValue(context.getELContext());

        myBean2.getText().setValue("action7");
    }

    // Using evaluateExpressionGet. NOTE: this is implemented since JSF 1.2!
    public void action8() {
        FacesContext context = FacesContext.getCurrentInstance();
        MyBean2 myBean2 = (MyBean2) context.getApplication()
            .evaluateExpressionGet(context, "#{myBean2}", MyBean2.class);

        myBean2.getText().setValue("action8");
    }

}
```


----------



## MrWhite (14. Jan 2010)

Das halte ich für super dreckig. Lieber Bijection von SEAM nutzen oder die erforderlichen Werte als HashTable oder so in die Session schreiben. 

Aber Beans auf diese Art und Weise kommunizieren zu lassen, ist verdammt hässlich.


----------



## Deadalus (14. Jan 2010)

Kannst du bitte erläutern was daran dreckig sein soll, sich über den FacesContext eine simple Referenz auf das Managed Bean geben zu lassen?Für mich sieht das nach einer sehr sauberen Lösung aus, die zudem noch nichtmal groß Ressourcen kosten wird. 

Hashtabellen in die Sessiondaten schreiben kostet bestimmt mehr Resourcen als eine Referenz auf ein bereits instanziertes Objekt zu erfragen.

Properitäre Frameworks wie SEAM kommen für mein Projekt sowieso nicht in Frage. Die Fähigkeiten der JEE müssen ausreichen.


----------



## MrWhite (14. Jan 2010)

Diese Technik verletzt meiner Ansicht nach das Prinzip der losen Kopplung. Ausserdem ist die von Bioharzard dargestellte Art & Weise des Zugriffs einfach dreckig und ein Graus. Das ist einfach unsauber und schlecht wartbar. Weder Compiler noch AppServer können diese Zugriffe auf Korrektheit prüfen.

Wenn Beans miteinander kommunizieren sollen, dann macht man das besser über einen sauberen Kanal.

Das Performance-Argument zieht rein gar nicht, denn hier gibt es kein Bottleneck und Wartbarkeit ist per se bei handelsüblichen Enterprise-Applikationen das kostbarere Gut. Die Resourcen, die es kostet, einen Hashtable in die Session zu schreiben sind ja wohl absolut vernachlässigbar. SEAM könnte übrigens in den J2EE Standard aufgenommen werden, ein Blick lohnt sich also.

Viele vertreten sogar die Ansicht, dass man JSF ohne SEAM ohnehin vergessen kann. Vor allem Convention over Configuration erspart einem viel Arbeit (Komponenten statt Managed Beans).


----------



## maki (14. Jan 2010)

> Diese Technik verletzt meiner Ansicht nach das Prinzip der losen Kopplung.


Ja, sehe ich genauso, aber ohne einen DI Mechanismus läuft es immer darauf hinaus: ResourceLookup

Hab selber diese "dreckige" Technik in JSF 1.1 eingesetzt, alternativen gab es damals keine


----------



## damien (18. Jan 2010)

maki hat gesagt.:


> Ja, sehe ich genauso, aber ohne einen DI Mechanismus läuft es immer darauf hinaus: ResourceLookup
> 
> Hab selber diese "dreckige" Technik in JSF 1.1 eingesetzt, alternativen gab es damals keine



Und mit JSF 2.0 ?


----------



## maki (18. Jan 2010)

Hab ich nie benutzt, wurde durch JSF 1.1 traumatisiert *g*


----------

