Im PhaseListener Service Methode aufrufen

internet

Top Contributor
hallo,
ich habe folgendes Problem:
Ich möchte beim Betreten der Seite überprüfen, ob ein User bereits aktiviert wurde.
Das mache ich über den PhaseListener
Im Link ist ein AktivierungsKey. Diesen bekomme ich auch durch ExternalContext extCtxt.
Nun muss ich aber eine Datenbankabfrage machen, ob zu irgendeinem User dieser Aktivierungsschlüssel gibt.
Diese Methode ist aber in einer Service Klasse.
Bei diesem Aufruf bekomme ich immer eine NullPointerException.
Demnach ruft der PhaseListener nicht die Service Klasse auf, in der diese Methode ist.
Muss ich irgendwo noch diese Service Klasse deklarieren (web.xml oder faces-config) ?

Hier die Methode im PhaseListener:
Code:
public void beforePhase(PhaseEvent event) {
		Map<String, Object> sessionMap = FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap();
		try {

			Object principal = SecurityContextHolder.getContext()
					.getAuthentication().getPrincipal();

			
			// Informationen zum eingeloggten Benutzer bekommen
			//UserDetails user = (UserDetails) principal;

			// Wenn der User noch nicht eingeloggt ist, sondern ein sog.
			// "anonymousUser" ist, dann

			if (principal.equals("anonymousUser")) {
				System.out.println("2");
				principal = null;
			}
			
			if (principal == null) {
							
				FacesContext jsf = FacesContext.getCurrentInstance();
				ExternalContext extCtxt = jsf.getExternalContext();
				String activateKey = extCtxt.getRequestParameterMap()
						.get("act");
				System.out.println("Activation KEy: " + activateKey);
				if (activateKey != null) {
					System.out.println("5");
					try {
						System.out.println("6");
						userSpring.findUserByActivationKey(activateKey);
						System.out.println("7");
					} catch (UserNotFoundException e) {
						
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
			}
		}

		catch (NullPointerException e) {
			sessionMap.clear();
		}

		System.out.println("Before Phase: " + event.getPhaseId());

	}



Der Aufruf in faces-config

Code:
	<lifecycle>
		<phase-listener>com.example.util.QueryPhaseListener</phase-listener>
	</lifecycle>
 
Ist Deine Service-Klasse die UserSpring?

Wie injectest Du diese?

So aus dem Stehgreif meine ich, dass PhaseListener keine Injections zulassen. Hol Dir Deine Service-Klasse mal über den FacesContext.
 
Ja, UserSpring ist meine Service Klasse.
Leider bin ich (noch nicht) der Experte.
Bezüglich Injecten:
Reicht das nicht, wenn ich im PhaseListener ein Getter + Setter habe für die UserSpring?
Wie geht das mit dem FacesContext?
Ich weiß wie man eine andere ManagedBean aufrufen kann:
zB:
AndereMgdBean andereBean = (AndereMgdBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("andereBean");

Geht das genauso, wenn ich die Service Klasse aufrufe? Also:
UserserviceImpl userserviceImpl = (UserserviceImpl) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userserviceImpl");
 
Ja, die kannst Du genauso ziehen, wenn es eine Sessionbean ist. Wie sieht denn der Code der Bean aus?
 
Die Service Klasse ist doch mit @Service annotiert.
Also sowas hier:
Code:
	@Service(UseradministrationService.NAME)
	@Transactional(propagation=REQUIRED)
	public class UseradministrationServiceImpl implements Serializable,UseradministrationService{// Hier alle Methoden, u.a. die Methode, die aufgerufen werden soll....}

Das heißt: Ich muss die Service Klasse bzw. die Methode in der Service Klasse über eine andere ManagedBean aufrufen?
 
Wie hast Du die Bean im JSF-Context bekannt gemacht?

Java:
<managed-bean>
    <managed-bean-name> userSpring </managed-bean-name>
    <managed-bean-class>my.package.userSpring</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>    
</managed-bean>

Entsprechend des Scopes muss Du Dir die Bean wie oben beschrieben laden.
 
Zuletzt bearbeitet von einem Moderator:
Also bisher habe ich in der faces-config gar keine bean bekannt gemacht.
Grund: Weil ich beim Starten der Applikation keine Methoden aufgerufen habe.
Erst wenn die index - Seite aufgerufen wurde kann man Methoden aufrufen.
zb User einloggen. Das funktioniert auch.

Aber nochmal die Frage: Die userSpring ist bei mir doch eine Service - Klasse und nicht
eine ManagedBean. Du gibst allerdings das an:

<managed-bean-name> userSpring </managed-bean-name>

Ist das so richtig?
 
Wenn ich Dich richtig verstanden habe, ist Deine Service-Klasse eine Spring-Bean. Damit diese im JSF-Context verfügbar ist, muss Du diese auch in der faces-context.xml deklarieren.

Alternativ kannst Du Dir die Bean auch über den Spring-Context holen. Dafür wäre ein entsprechender Eintrag in der web.xml notwendig - falls dieser nicht schon vorliegt.

Ich würde Dir ansonsten google ans Herz legen und nach "spring bean jsf context" oder ähnliches suchen.

edit:

Aber nochmal die Frage: Die userSpring ist bei mir doch eine Service - Klasse und nicht
eine ManagedBean.?
Sie ist ein Service im Spring-Sinne und eine Managed-Bean im JSF-Sinne. 🙂
 
Hallo,
also ich habe in der beforePhase nun folgender Methodenaufruf
Code:
UseradministrationServiceImpl userSpring = (UseradministrationServiceImpl) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userSpring"); 
userSpring.findUserByActivationKey(activateKey);

Hier fliegt er mir aber immer raus.
In der faces-config steht bei mir das hier:

Code:
	<managed-bean>
		<managed-bean-name>userSpring</managed-bean-name>
		<managed-bean-class>com.example.useradministration.awk.UseradministrationServiceImpl</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>


Warum bekomme ich da immer eine NullpointerExcption?
Was mache ich falsch?
 
Ist denn die userSpring null oder fliegt diese Exception in der Methode? Hast Du da mal nen Debugger drüber laufen lassen?
 
Hast Du Dir den Log Deines Application-Servers mal angesehen? Dort müsste zu finden sein, welche Beans initialisiert werden, bzw. wo es Probleme gibt.
 
ja, habe ich.
Sehe ich aber nicht.
Ich hatte eine Bean gleich genannt - dies habe ich nun aber geändert

Es scheint mir, dass das in der faces-config nicht stimmt?
 
Dein Aufruf ist Falsch!

Am besten in eine Utility-Klasse auslagern:

FacesUtil.java
Code:
public class FacesUtil{

public static <T> T getManagedBean(final FacesContext facesContext, final String beanName, final Class<T> expectedType) {
		
		ELContext elContext = facesContext.getELContext();
		Application application = facesContext.getApplication();
		ValueExpression ve = application.getExpressionFactory().createValueExpression
                                                                    (elContext, "#{" + beanName + "}", expectedType);
		T bean;
		try {
		
			bean = (T) ve.getValue(elContext);
		} catch (ClassCastException e) {
		//handle me
		}

		return bean;
	}
}

Aufruf:

Code:
UseradministrationServiceImpl userSpring = (UseradministrationServiceImpl) FacesUtil.getManagedBean(facesContext, "userSpring", UseradministrationServiceImpl.class); 

userSpring.findUserByActivationKey(activateKey);

mit
Code:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userSpring");
lädst du Parameter die in der SessionMap abgelegt worden sind!

Grüße

PS: Ich würde die Spring und die ManagedBean nicht in eine Klasse verpacken!
 
Sollte die Bean nicht in der Sessionmap abgelegt sein? Ich meine, dem ist so.

Wobei Dein Ansatz natürlich sauberer ist. Ich würde jedoch neben der ClassCastExcpetion noch eine NPE fangen (oder dies vorher prüfen), da das Laden einer Bean über den Namen allgemein recht fehlerträchtig sein kann. 🙂
 
Wenn ich dein Code einfüge, dann bekomme ich für facesContext ein Error.
Code:
facesContext cannot be resolved to a variable
 
Um Dir bei solchen Fehlern helfen zu können ist es immer sinnvoll, wenn Du genau die Stelle findest, die den Fehler wirft. Sprich einmal den Debugger starten und schauen, bis wohin Du kommst.

Und dann hilft es immer, den Fehler auch mit entsprechender Fehlermeldung zu posten. 🙂
 
In der Phase Util habe ich doch den Parameter facesContext. In der Listener Klasse habe ich keine Variable namens facesContext. Das ist der Fehler. Wie muss ich die Variable deklarieren? Außerhalb der Methode oder in der Methode ?

Ps: Besten Dank euch beiden schon mal
 
Du hast doch einen FacesContext. Nur bei Dir heißt dieser jsf und nicht facesContext wie bei JimPanse.

So müsste der Aufruf aussehen:

Java:
UseradministrationServiceImpl userSpring = (UseradministrationServiceImpl) FacesUtil.getManagedBean(jsf, "userSpring", UseradministrationServiceImpl.class); 

userSpring.findUserByActivationKey(activateKey);

Oder verstehe ich Dich falsch?

Versuch bitte zukünftig zu beschreiben, wo der Fehler auftaucht. Ist das ein Kompiler-Fehler? Oder sagt Dir das schon Deine Entwicklungsumgebung. Dann kann Dir besser geholfen werden.
 
2 Möglichkeiten:


Code:
public void beforePhase(PhaseEvent arg0){

//1. Möglichkeit
arg0.getFacesContext();

//2.Möglichkeit
FacesContext context = FacesContext.getCurrentInstance();
}

Du kannst die Methode auch umschreiben und dir den FacesContext in der Utility-Klasse holen!
 

Neue Themen


Zurück
Oben