# Freischaltung per Freischaltlink implementieren



## internet (28. Mrz 2011)

Hallo,
		ich möchte gerne ein Portal programmieren, bei dem man sich registrieren kann.
		Dies ist kein Problem.
		Nun soll der User einen Freischaltlink per Email zugeschickt bekommen.
		Wenn er diesen Freischaltlink öffnet, dann soll er freigeschaltet sein.
		Folgende Technologie:
		Spring, Spring Security, MySQL, JSF, Tomcat.

		1. Wie sieht es in der Datenbank aus? Einfach ein Boolean - Attribut: freigeschaltet (0 oder 1)?
		2. Wie soll ich das überprüfen, ob es den Link tatsächlich gibt?

		Kann mir bitte jemand weiterhelfen, oder hat das gar schon selbst implementiert?


----------



## brauner1990 (28. Mrz 2011)

Du machst eine Tabelle/Objekt, bei der/dem du Freischaltlinks und benutzernamen speicherst. Bei Aufruf wird das Objekt gelöscht und bei Benuzter eine eigenschaft auf true gesetzt.


----------



## hyperion (28. Mrz 2011)

Ich würde bei der Registrierung eine ID generieren und diese zum einen in die Datenbank schreiben und zum anderen als GET-Parameter an den Link hängen. Der Link ist dann bei jedem User gleich, nur der Parameter unterscheidet sich.

Wenn der Benutzer auf den Link klickt, wird bei dem User der Account freigeschaltet bei dem die ID in der DB steht.

Gruß hyperion


----------



## internet (28. Mrz 2011)

Okay, das hätte ich auch so gemacht.
Aber wie mache ich das mit der Überprüfung der URL?
Ich muss dazu ja eine Datenbankabfrage machen...
Hat jemand dafür den Code - wäre echt super


----------



## internet (12. Apr 2011)

keine weitere Ideen?


----------



## Sym (12. Apr 2011)

Was für Code möchtest Du denn sehen?

Du brauchst eine xhtml-Seite, die get-Parameter erwartet. Dann liest Du in der Bean den Parameter aus und vergleichst den Eintrag in der Datenbank. Danach setzt Du den Benutzer auf aktiv.

Wo genau brauchst Du dabei Hilfe?


----------



## internet (12. Apr 2011)

Ich brauche Hilfe bei folgendes:
	Wenn der User die Seite aufruft, dann soll eben diese Methode augerufen werden,
	die dann in der Datenbank schaut, ob es diesen Freischaltlink gibt.
	Gibt es diesen, wird der User freigeschaltet.
	Also ich benötige Hilfe wie ich diese Methode in der xhtml - Seite aufrufen kann.
	Desweiteren in welcher Klasse soll sich dann diese Methode befinden?
	Muss ich das dann in der web.xml angeben oder wie geht dies?


----------



## SlaterB (12. Apr 2011)

für ganz grundsätzliche Tipps, wie du in xhtml oder was immer komisches deine Webanwendung ist, einen Datenbankzugriff hinbekommst, 
scheint das hier ein falsches Thema, mit hochspeziellen 'Freischaltung per Freischaltlink implementieren' vergraulst du ja 99,9%, die vielleicht allgemein etwas zum Datenbankzugriff im Web wissen,

ich persönlich kann dabei nicht helfen, aber mal allgemeine Grundsätze für Java-Webanwendungen zitieren:
Anzeige-Seiten wie JSP oder bestimmt auch xhtml, was immer das ist, sollten keine einzige Zeile Java-Code enthalten,
dafür gibt es Servlets bzw. vergleichbare echte Java-Klassen, das sollte dir was sagen wenn du JSF nennst,

wie man in einem normalen Webprojekt einen normalen Datenbankzugriff hat, ist ein Thema für die 300 Seiten Grundlagen zu einen Webprojekt im gewählten Framework,
was immer da an Informationen herauskommt, wird irgendwo abgelegt, ob in Session, Request, Beans oder wer weiß was in Sonderframeworks,
Anzeige-Seiten werten dann diese fertigen Daten aus


----------



## Sym (12. Apr 2011)

Kurz gesucht:

http://www.java-forum.org/allgemeines-ee/98254-get-parameter-auslesen.html

Da wird z.B. auf das Auslesen von Get-Parametern eingegangen.

Oder auch hier:

java - How to create a GET request with parameters, using JSF and navigation-rules? - Stack Overflow

Gefunden wie folgt:

Google -> jsf get parameter -> Suchen


----------



## Stroker89 (13. Apr 2011)

Eine recht simple Methode, wäre auch bei der Registrierung die Daten des User in eine temporäre Tabelle zu speichern und zusätzlich z.B. einen Hash (beispielsweise MD5) aus der E-Mail Adresse zu erzeugen und mit zu speichern. Dann ein Servlet schreiben, dass beim Aufruf (mit dem Hash) den temporären Benutzer in die "echte" User Tabelle schreibt und aus der temporären löschen.

Beim Login natürlich nur die "echte" Tabelle gebrauchen. 

Das wäre nicht schwer zu implementieren.

Gruß


----------



## internet (13. Apr 2011)

So, ich habe es nun auch schon fast:
Der Key wird mir in der URL ausgelesen.
Jetzt fehlt mir nur noch das Setzen von Aktiv auf Inaktiv: Also den Eintrag in der DB.
Mein Problem ist nun, dass die Methode *userSpring.findUserByActivationKey(activateKey)*; nicht aufgerufen wird.
Woran liegt das? Ich gebe auf der Konsole Zahlen aus, um zu prüfen wo er hingeht.
Zu 5 und 6 geht er, aber zu 7 nicht. Er geht aber auch nicht in den catch Block.

Hier die Methode:

```
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());

	}
```



Folgendes steht in der faces-config

```
<managed-bean>
		<managed-bean-name>workaround</managed-bean-name>
		<managed-bean-class>com.mopist.util.WorkaroundMgdBean</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
		<managed-property>
			<property-name>userSpring</property-name>
			<value>#{UseradministrationServiceImpl}</value>
		</managed-property>
	</managed-bean>


	<lifecycle>
		<phase-listener>com.example.util.QueryPhaseListener</phase-listener>
	</lifecycle>
```


----------



## SlaterB (13. Apr 2011)

allem Anschein nach gibt es eine NullPointerException, die du weiter außen fängst und dann nicht ausgibst,
baue dort auch Log ein (generell unbedingt! oder noch besser dieses catch entfernen, dann wird hoffentlich allgemein irgendwo der Fehler ausgegeben), 
für den Moment z.B. temporär

} catch (UserNotFoundException e) {
auf
} catch (Exception e) {
ändern


----------



## internet (13. Apr 2011)

Ja, du hast recht, da wirft es mir eine Nullpointer Exception.
Woran kann das liegen?


----------



## Sym (13. Apr 2011)

Am besten Du nutzt Deinen Debugger und schaust, was das Problem ist.

edit: eventuell <value>#{UseradministrationServiceImpl}</value> falsch geschrieben? Oder nicht existent?


----------



## internet (13. Apr 2011)

Ok,
also die Klasse UseradministrationServiceImpl wird nicht aufgerufen.
Daher immer eine Nullpointer Exception.
Nein, nicht falsch geschrieben.

Stimmt das überhaupt so, dass er beim Laden dann die Klasse UseradministrationServiceImpl aufruft?
Oder wo wie mache ich das in web.xml oder faces-config


----------



## internet (18. Apr 2011)

Kann mir niemand weiterhelfen?
		Wie gesagt: Den Aktivierungslink bekomme ich (Der PhaseListener wird aufgerufen).
		Aber die Methode in der Service Klasse wird nicht aufgerufen.
		Also generell die Service Klasse wird nicht aufgerufen.


----------



## SlaterB (18. Apr 2011)

wenn bei dir grundlegende Abläufe in JSF nicht funktionieren, dann solltest du entsprechende Tutorials/ Beispielprogramme anschauen,
oder ein neues Thema starten 'JSF-Grundlage xy funktioniert nicht'

ich persönlich kann zu JSF-Internas nichts sagen und in einem Thema 'Freischaltung per Freischaltlink implementieren' werden nicht so viele reinschauen,
mit Freischaltlinks hat das doch inzwischen nichts mehr zu tun oder?


----------



## Sym (18. Apr 2011)

Wenn Dir jemand helfen soll, dann musst Du das Problem auch richtig beschreiben.

Was heißt "Also generell die Service Klasse wird nicht aufgerufen"? Inwiefern wird eine Klasse aufgerufen? Wo genau fliegt die NPE, bzw. was bei Dir ist null? Konntest Du Spring-Beans schon irgendwo injecten? Ist das überhaupt eine Spring-Bean? Wie sieht diese aus?

Und SlaterB hat recht. Du musst das eigentliche Problem erkennen und dafür einen Thread starten.


----------



## internet (18. Apr 2011)

Ich habe ein neues Topic eröffnet:
http://www.java-forum.org/web-tier/116757-phaselistener-service-methode-aufrufen.html#post751920

		Wie gesagt: Der PhaseListener ruft nicht die Methode bzw. die Klasse im Anwendungskern (Service Klasse) auf.
		Muss man diese Service Klasse irgendwo noch deklarieren, dass diese beim Start aufrufbar ist?


----------

