# JSF: Bei Seitenaufruf eine Methode starten



## Millman (27. Mai 2010)

Hey Leute,

ich möchte, sobald meine Index-Seite aufgerufen wird eine Methode starten lassen, die wiederum eine Listenvariable in der BackingBean der Index-Seite befüllt, so dass sofort eine DataGrid mit dieser Liste angezeigt werden kann.

Wie schaffe ich das? Über den Konstruktor Index() bekomme ich immer eine Fehlermeldung, weil er scheinbar irgendwie mit meiner EJB nicht klarkommt. Lasse ich die Liste manuell befüllen, indem ich die befüllende Methode auf einen CommandButton lege, funzt alles ohne Probleme.


----------



## internet (27. Mai 2010)

das musst du in der web.xml deklarieren...


----------



## Millman (27. Mai 2010)

Danke, hast du vll auch einen Link dazu, wo ich genau nachlesen kann, wie das geht?


----------



## MrWhite (27. Mai 2010)

Wüsste nicht, wie das mit der web.xml geht und ob es überhaupt geht, ohne eigene Lifecycle-Listener einzusetzen.

Aber wenn du zusätzlich noch JBoss Seam einsetzt, kannst du das in einer Datei namens *pages.xml* definieren:


```
<action execute="#{aBean.anAction}" />[/xml]
```


----------



## internet (27. Mai 2010)

*web-xml *
 <context-param>
	<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
	<param-value>/WEB-INF/jsf-config/anwendung.taglib.xml</param-value>
</context-param>	




*anwendung.taglib.xml*
<?xml version="1.0"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">

<namespace>http://anwendung.de</namespace>

	<function>
		<function-name>nameDerMethode</function-name>
			<function-class>
				ort deiner Bean (de.anwednung.ui.Bean)
			</function-class>

			<function-signature>
				java.util.List methodeName()
			</function-signature>
	</function>
</facelet-taglib>


So sollte es gehen


----------



## MrWhite (27. Mai 2010)

internet hat gesagt.:


> *web-xml *
> <context-param>
> <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
> <param-value>/WEB-INF/jsf-config/anwendung.taglib.xml</param-value>
> ...



Das ist wohl ne klare Themaverfehlung! Hier wird nur eine Funktion definiert, die dann im EL genutzt werden kann. Das wird aber nicht automatisch bei einem Page Request ausgeführt!

Wenn der OP SEAM nicht nutzen will, könnte er noch mittels Javascript und AJAX einen quick & dirty Workaround schaffen.


----------



## Millman (27. Mai 2010)

Gibt es für so etwas denn nicht einen anderen Weg als einen Workaround?

Ich meine, ich möchte auf meiner Startseite ja eigentlich nur eine Liste haben, welche zuvor aus der Datenbank gezogen wird. So etwas gibt es doch heutzutage auf jeder Website.

Aber falls es nur mit einem Workaround mit Ajax und JS geht, wie würde dieser aussehen?


----------



## Luu (27. Mai 2010)

Richfaces Lösung: 


```
<body onload="execute();">
....
</body>

<a4j:jsFunction name="execute" action="#{bean.action}" reRender="IDsToRerender" ... />
```


----------



## MrWhite (27. Mai 2010)

Millman hat gesagt.:


> Gibt es für so etwas denn nicht einen anderen Weg als einen Workaround?
> 
> Ich meine, ich möchte auf meiner Startseite ja eigentlich nur eine Liste haben, welche zuvor aus der Datenbank gezogen wird. So etwas gibt es doch heutzutage auf jeder Website.
> 
> Aber falls es nur mit einem Workaround mit Ajax und JS geht, wie würde dieser aussehen?



JBoss SEAM einsetzen oder einen Phase-Listener schreiben, der entsprechend definierte Aktionen für Page Requestes durchführt. Das ist aber aufwendig.

JBoss Seam hat auch noch die @Create-Annotation um eine Methode beim Erstellen einer Komponenten-Instanz aufzurufen (Wäre für dich unter Umständen auch eine Lösung). JSF ohne SEAM ist echt grausam (mit SEAM auch noch, aber ... naja).


----------



## JanHH (28. Mai 2010)

Frage mich da wo das eigentliche Problem liegt, oder bin ich einfach zu naiv!? In der jsf-Seite gibts irgendwo <h:datatable value=#{meineBean.liste}">. In meineBean gibts eine getter-Funktion "getList", die die Liste aus der Datenbank liest. Und schon ist die gewünschte Funktionalität da. Wo ist das Problem?

Ansonsten, klarer Fall, seam, @DataModel und Factory-Methoden..


----------



## bananenkasper (28. Mai 2010)

PhaseListener ist jetzt auch nicht das Problem:


```
public class QueryPhaseListener implements PhaseListener {
	@Override
	public void beforePhase(PhaseEvent e) {
		// do stuff just before page loads
	}
	@Override
	public PhaseId getPhaseId() {
		return PhaseId.RENDER_RESPONSE;
	}
	@Override
	public void afterPhase(PhaseEvent e) {
	}
```

in der faces.config:

```
<lifecycle>
      <phase-listener>x.y.z.QueryPhaseListener</phase-listener>
   </lifecycle>
```


----------



## MrWhite (28. Mai 2010)

bananenkasper hat gesagt.:


> PhaseListener ist jetzt auch nicht das Problem



Ja, aber implementier da jetzt mal die geforderte Logik rein. Sowas will doch kein Mensch machen. Andere Frameworks haben Module und Handler die man vorschalten kann.

Einen leeren FaceListener zu präsentieren ... tsss, das ist doch trivial.


----------



## bananenkasper (28. Mai 2010)

MrWhite hat gesagt.:


> Ja, aber implementier da jetzt mal die geforderte Logik rein. Sowas will doch kein Mensch machen. Andere Frameworks haben Module und Handler die man vorschalten kann.
> 
> Einen leeren FaceListener zu präsentieren ... tsss, das ist doch trivial.



tsssssssssssssssss, sind wir nicht alle ein bisschen trivial?


```
public class QueryPhaseListener implements PhaseListener {
    public static <V> V getManagedObject(String elString, Class<V> c) {
		Application a = context.getApplication();
		V v = c.cast(a.evaluateExpressionGet( FacesContext.getCurrentInstance(), elString, c));
		return v;
	}
    @Override
    public void beforePhase(PhaseEvent e) {
        final SessionBean sBean = getManagedObject("#{sessionBean}",
				SessionBean.class);
		if (sBean == null) {
			log.warn("no sessionBean found!");
			return;
		}
        sBean.setData(/** get data from DB */);
    }
    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }
    @Override
    public void afterPhase(PhaseEvent e) {
    }
}
```


----------



## MrWhite (28. Mai 2010)

bananenkasper hat gesagt.:


> tsssssssssssssssss, sind wir nicht alle ein bisschen trivial?
> 
> 
> ```
> ...



:bloed: Das hat mal wieder null mit der Frage vom OP zu tun, aber na gut.

Manche Menschen...


----------



## Deadalus (28. Mai 2010)

Was zum Teufel macht ihr hier alle? 

*Problem des Users: * Eine Methode soll ausgeführt werden sobald ein User die Web Applikation lädt:

*Lösung:*


BackingBean bekommt einen Session oder View Scope  -> Bean wird erzeugt wenn Nutzer die Seite aufruft. 
Methode die ausgeführt werden soll wird mit @PostConstruct annotiert -> Methode wird ausgeführt wenn Bean instanziiert wird!

fertig!


----------



## internet (22. Jul 2010)

hat hier jemand eine Lösung gefunden bzw. implementiert?


----------

