# Action-Methode soll Ausgabe auf der Responsepage steuern



## Andreas29 (12. Mrz 2008)

Hi Leute,

ich habe eine kurze Frage:
Kann ich in JSF irgendwie in einer Action-Methode steuern, was auf der Responsepage an Text ausgegeben wird? Sehr allgemein formuliert, ich weiß, daher ein paar mehr Details:
Ich habe mehrere action-Methoden, die unterschiedliche Tests ausführen. Im Moment habe ich für die Ergebnisausgabe eine statische Seite, die einfach aussagt, dass der Test erfolgreich war. Diese Seite würde ich jetzt gerne mit Infos anreichern, die mir die action-Methode des Tests liefern soll und das ganze, wenn es geht, schön sauber getrennt (sprich ich möchte nur ungern in der action-Methode direkt auf irgendwelche UI-Elemente zugreifen). Gibt es da eine Lösung?

Grüße und vielen Dank für jede Hilfe!
Andreas


----------



## schoeso (12. Mrz 2008)

Hi,

deine Action Methode führt Tests durch und erzeugt Ergebnisstrings. Diese Strings legst du z.B. in den Attributen einer Managed-Bean ab. Die GUI Elemente deiner Ergebnisseite bindest du an die getter Methoden der entsprechenden Attribte des Managed-Bean.

War es das?

Gruß

Arndt

www.schoenberg-schoenberg.de


----------



## Andreas29 (13. Mrz 2008)

Hi Arndt,

erstmal danke für Deine Antwort.
So in der Art habe ich mir das vorgestellt, ja. Was mir nur noch nicht ganz klar ist, ist die Tatsache, wie die Managed Bean dann in meine JSF Seite kommt. Ich meine, wenn ich jetzt in meiner Action-Methode eine neue Instanz meiner Bean-Klasse erzeuge und mit Werten fülle, werde ich die ja noch irgendwohin "packen" müssen, damit die Werte bei der GUI ankommen. Und dieses irgendwohin ist mein Problem.

Beispiel (fiktiv, zeigt aber das Problem...):

```
public String actionMethod() {
    // meine Managed Bean
    MessageBean bean = new MessageBean();
    // ein Attribute setzen
    bean.setMessage("Test blah fasel blubb");
    // und nun? wenn ich jetzt weiter nichts mache, wird der GC die Instanz wegräumen, also muss sie noch irgendwo hin, nur wo?
}
```

Dank dir für Deine Hilfe.

Grüße,
Andreas


----------



## Andreas29 (13. Mrz 2008)

Hi,

ich habe jetzt festgestellt, das es funktioniert, wenn ich die neue Bean in der requestMap speichere. Nur weiß ich nicht, ob das so der richtige Weg ist, da mich der Name requestMap doch etwas verwirrt, denn schließlich geht es ja um die response und nicht um den request. Weißt jemand, ob das so gewollt und richtig ist? Sprich, ich meine die Map, auf die ich mittels folgenden Code zugreifen kann:


```
FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
```

Grüße,
Andreas


----------



## Guest (23. Mrz 2008)

Hallo,

lass dich nicht vom Namen irritieren, die Request-Map ist einfach eine Map, die sozusagen einen Request lang lebt, die Daten bleiben also erhalten, bis der Response fertig ist (genauer gesagt halt, bis der Servlet-Container per Callback sagt, dass der Request bearbeitet wurde). Der Request-Scope (um das jetzt mal von der Map zu abstrahieren) ist also schon genau der richtige Scope für derartige Nachrichten.

Was aber vielleicht nicht ganz so gut gelöst ist, ist, dass du die Bean selbst verwaltest. "Testfreundlicher" und somit besser wäre es, wenn du dir diese MessageBean von der Managed-Bean Facility injizieren lässt. Die MessageBean bekommt als Scope natürlich wieder request gesetzt, da das, wie wir bereits festgestellt haben, der beste Scope hierfür ist. 


```
<managed-bean>
  

  <managed-bean-name>...</managed-bean-name>
  ...

  <!-- Achtung: Diese Bean darf nur im Request Scope liegen, das hängt damit zusammen, dass
      man Request-Scoped Beans nur in Request-Scoped Beans injizieren kann. Siehe JSF Tutorial
      deiner Wahl dazu. -->
  <managed-bean-scope>request</managed-bean-scope>
 
  <managed-property>
    <property-name>messageBean</property-name>
    <value>#{messageBean}</property-name>
  </managed-property>
</managed-bean>

<managed-bean>
  <managed-bean-name>messageBean</managed-bean-name>
  <managed-bean-class>dein.package.MessageBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  
  <!-- Prinzipiell könntest du natürlich auch einen "größeren Scope" wie z.B. session verwenden,
         damit du diese Bean auch in Session-Scoped Beans injizieren kannst, aber ideal ist es halt
         nicht, wenn die Bean länger als nötig existiert. Wenn es wirklich nur darum geht, diese Bean
         in eine Session-Scoped Bean zu injizieren, gibt es bessere Alternativen, das zu implementieren. -->

</managed-bean>

// deine ActionBean.java
public class .... {

  private MessageBean messageBean
  
  public void setMessageBean(MessageBean messageBean) {
    this.messageBean = messageBean;
  }

  public String actionBean() {
    // Nachricht ganz normal setzen
    messageBean.setMessage("Test blah fasel blubb");
  }
}
```

So wie du siehst, kannst du auf diese Art Informationen speichern, ohne, dass du dich an die JSF API bindest. Dadurch werden z.B. Tests wesentlich vereinfacht (es ist zwar möglich einen FacesContext zu mocken, aber eben wesentlich aufwendiger als diese Variante). In anderen Fällen bleibt dir aber oft eh nichts anderes übrig, als die Variante über den programmatischen Zugriff auf die Bean zu verwenden, aber am besten lässt du in dem Fall dann einfach nochmal von dir hören. ;-)

Btw. es gäb auch das Konzept der FacesMessages, vielleicht wäre das auch was für dich, wobei du dich damit natürlich schon wieder an die JSF API binden würdest.

grüße,
unkreativ


----------

