Zurück-Button des Browsers macht Probleme

Status
Nicht offen für weitere Antworten.

PeterRRR

Mitglied
Hallo!

Ich hab ein JSF-Formular mit 2 Radiobuttons. Dem Benutzer wird eine Frage gestellt und einer der 2 Radios ist die richtige Antwort. In einem Bean sind die Fragen inkl. Antwortmöglichkeiten und korrekter Antwort gespeichert (in einer Liste). Bei Klick auf den Bestätigungs-Button werden im Bean die Antworten sowie der Fragetext geändert (nächstes Element der Liste wird in Variable gespeichert) und die selbe Seite wird mit den veränderten Werten (also neuer Frage und neuen Antworten, ausgelesen aus eben genannter Variable) und einem Hinweis ob die Antwort des Benutzers auf die vorhergehende Frage korrekt war, neu geladen. Wieder ist eine der beiden Antworten korrekt und das Spiel fängt wieder von vorne an. Am Ende wird eine Punktzahl angezeigt.

Das Problem ist jetzt der Zurück-Button des Browsers, klickt man auf diesen, kommt man ja zur letzten Frage zurück und kann die Antwort theoretisch nochmal ändern. Das funktioniert aber auch nicht wirklich, sondern man bekommt einen Validierungsfehler für das Formular. Ich hätte allerdings gerne, dass bei Verwendung des Zurückbuttons und anschließendem Klick auf den Button (also beim Versuch die Antwort nachträglich zu ändern) auf eine entsprechende Seite weitergeleitet wird, die eine Meldung anzeigt, dass das nachträgliche Ändern von Antworten nicht möglich ist.
Ich probiere schon lange herum und krieg es einfach nicht hin.
Hat jemand einen Tipp, wie ich das anstellen könnte? Danke schon jetzt für jede Hilfe!

lg
Peter
 

PeterRRR

Mitglied
Hat wirklich niemand eine Idee, nicht einmal eine kleine? :bahnhof:

Das kann doch eigentlich gar nicht schwer sein, es muss doch irgendwie eine Möglichkeit geben, nur welche?

lg
 

Terminator

Aktives Mitglied
Müsstest dich vor der Validierung in den Zyklus einklingen bsw per PhaseListener.
Dann irgendwelche Session Werte checken, ob Frage schon beantwortet wurde und sofort zu RenderResponse jumpen.
Über ein rendered Flag dann die Fragen nicht mehr anzeigen, dafür den Hinweistext.
 

PeterRRR

Mitglied
Danke für die Antwort. Leider sagt mir das jetzt momentan nicht so viel, könntest du das evtl. genauer erklären bzw. gibt es zu diesem Thema vielleicht sogar ein Tutorial?
Danke!

lg
Peter
 

Terminator

Aktives Mitglied
Na die Zyklen sollte man aber schon kennen wenn man JSF proggt:

1. Restore View
2. Apply Request Values
3. Process Validations
4. Update Model Values
5. Invoke Application
6. Render Response



PhaseListner:

public class EPhaseTracker implements PhaseListener, Serializable
{
public PhaseId getPhaseId()
{
return PhaseId.ANY_PHASE;
}
public void beforePhase(PhaseEvent e)
{
System.out.println("EPhaseTracker." + e.getPhaseId() + " - before");
}
public void afterPhase(PhaseEvent e)
{
System.out.println("EPhaseTracker." + e.getPhaseId() + " - after");
}
}



faces-config.xml

<lifecycle>
<phase-listener>EPhaseTracker</phase-listener>
</lifecycle>



Mit getPhaseId kannste festlegen wo du dich einklingen willst
 

PeterRRR

Mitglied
Nochmal danke!
Ich hätte jetzt grundsätzlich mal den PhaseListener implementiert, das war ja nicht so das Problem, allerdings ohne konkrete Funktion außer einer einfachen Textausgabe. Mein konkretes Problem jetzt:

Wie kann ich denn checken, ob die Frage schon beantwortet wurde - sprich, wie weiß ich denn, welche Frage dem Benutzer gerade angezeigt wird, wenn er mittels Zurück-Button zurückgegangen ist - der Server bekommt das ja nicht wirklich mit, oder? Wie bereits gesagt, in meinem Bean ist eine Liste mit Fragen wovon immer genau eine in eine eigene Variable gespeichert wird, diese Variable wird dann dem Benutzer mittels JSF angezeigt. Geht der Benutzer jetzt zurück und beantwortet eine Frage nochmal, "glaubt" der Server, der Benutzer beantwortet die Frage, die in der Variable gespeichert ist, das ist ja das eigentliche Problem.

lg
Peter
 

PeterRRR

Mitglied
Ich hab jetzt mal ein sehr einfaches Beispiel erstellt, das mein Problem deutlich machen sollte:

Frage.java

Java:
package test;

public class Frage {

	private String frage;
	private String antwort1;
	private String antwort2;
	private String korrekt;
	
	public Frage(String f, String a1, String a2, String k)
	{
		setFrage(f);
		setAntwort1(a1);
		setAntwort2(a2);
		setKorrekt(k);
	}
	
	public String getFrage() {
		return frage;
	}
	public void setFrage(String frage) {
		this.frage = frage;
	}
	public String getAntwort1() {
		return antwort1;
	}
	public void setAntwort1(String antwort1) {
		this.antwort1 = antwort1;
	}
	public String getAntwort2() {
		return antwort2;
	}
	public void setAntwort2(String antwort2) {
		this.antwort2 = antwort2;
	}
	public String getKorrekt() {
		return korrekt;
	}
	public void setKorrekt(String korrekt) {
		this.korrekt = korrekt;
	}
}

MeineFrage.java (Bean)

Java:
package test;

import java.io.Serializable;
import java.util.ArrayList;
import javax.faces.event.ActionEvent;

public class MeineFrage implements Serializable{

	private static final long serialVersionUID = 1L;
	private ArrayList<Frage> frageliste = new ArrayList<Frage>();
	private Frage aktuelleFrage;
	private int counter = 0;
	private boolean ende = false;
	private String userantwort;
	private int richtigeAntworten = 0;
	
	public MeineFrage()
	{
		frageliste.add(new Frage("Frage 1", "Antwort 1.1", "Antwort 1.2", "Antwort 1.1"));
		frageliste.add(new Frage("Frage 2", "Antwort 2.1", "Antwort 2.2", "Antwort 2.2"));
		frageliste.add(new Frage("Frage 3", "Antwort 3.1", "Antwort 3.2", "Antwort 3.1"));
		aktuelleFrage = frageliste.get(counter);
	}
	
	public void checkAntwort(ActionEvent e)
	{
		if(getUserantwort().equals(aktuelleFrage.getKorrekt()))
			richtigeAntworten++;
		
		counter++;
		
		if(counter==frageliste.size())
			ende=true;
		else
			aktuelleFrage = frageliste.get(counter);
	}

	public String getUserantwort() {
		return userantwort;
	}

	public void setUserantwort(String userantwort) {
		this.userantwort = userantwort;
	}
	
	public ArrayList<Frage> getFrageliste() {
		return frageliste;
	}

	public void setFrageliste(ArrayList<Frage> frageliste) {
		this.frageliste = frageliste;
	}

	public int getRichtigeAntworten() {
		return richtigeAntworten;
	}

	public void setRichtigeAntworten(int richtigeAntworten) {
		this.richtigeAntworten = richtigeAntworten;
	}

	public boolean isEnde() {
		return ende;
	}

	public void setEnde(boolean ende) {
		this.ende = ende;
	}

	public Frage getAktuelleFrage() {
		return aktuelleFrage;
	}

	public void setAktuelleFrage(Frage aktuelleFrage) {
		this.aktuelleFrage = aktuelleFrage;
	}
}

faces-config.xml

Code:
	<managed-bean>
		<managed-bean-name>frage</managed-bean-name>
		<managed-bean-class>test.MeineFrage</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>

test.jsp (Auszug)

Java:
<f:view>
	<html>
		<head>
			<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
			<title>Test</title>
		</head>
		<body>
			<h:form id="antwortForm" rendered="#{!frage.ende}">
				<h:outputText value="#{frage.aktuelleFrage.frage}" />
				<h:selectOneRadio layout="pageDirection" id="antworten" value="#{frage.userantwort}">
					<f:selectItem id="antwort1" itemLabel="#{frage.aktuelleFrage.antwort1}" itemValue="#{frage.aktuelleFrage.antwort1}" />
					<f:selectItem id="antwort2" itemLabel="#{frage.aktuelleFrage.antwort2}" itemValue="#{frage.aktuelleFrage.antwort2}" />
			   	</h:selectOneRadio>
			   	<h:commandButton value="Klick" actionListener="#{frage.checkAntwort}" />
			</h:form>
			<h:outputText value="#{frage.richtigeAntworten}" rendered="#{frage.ende}" />
		</body>
	</html>
</f:view>
 

JanHH

Top Contributor
Kannst Du nicht einfach die aktuelle Frage als hidden Value mit in die Seite einbauen, und dann in checkAntwort überprüfen, ob die Frage, die in dem hidden Value angegeben ist, auch die ist, die erwartet wird? Und wenn dies nicht der Fall ist, kann man davon ausgehen dass der User rumnavigiert hat, entsprechend einen Hinweistext anzeigen und einfach nochmal die aktuelle Frage wiederholen.
 

PeterRRR

Mitglied
Das hatte ich mir auch schon einmal gedacht, bevor ich hier gepostet hab, nur wie soll ich das anstellen?

Wenn ich als Wert für das Hidden-Input den Text der aktuellen Frage nehme, also so:

Code:
<h:form id="antwortForm" rendered="#{!frage.ende}">
	<h:outputText value="#{frage.aktuelleFrage.frage}" />
	<h:selectOneRadio layout="pageDirection" id="antworten" value="#{frage.userantwort}">
		<f:selectItem id="antwort1" itemLabel="#{frage.aktuelleFrage.antwort1}" itemValue="#{frage.aktuelleFrage.antwort1}" />
		<f:selectItem id="antwort2" itemLabel="#{frage.aktuelleFrage.antwort2}" itemValue="#{frage.aktuelleFrage.antwort2}" />
	</h:selectOneRadio>
	<h:inputHidden value="#{frage.aktuelleFrage.frage}" />
	<h:commandButton value="Klick" actionListener="#{frage.checkAntwort}" />
</h:form>

bringt mir das garnichts, weil der Wert dann ja mit getter/ setter des Textes der aktuellen Frage verknüpft ist fünf Zeilen weiter oben im Code im Output-Text der Fall, das Hidden-Input wäre also gänzlich sinnlos.

Verknüpfe ich das Hidden-Input aber mit einer eigenen String-Variable, beispielsweise so:

Code:
<h:inputHidden value="#{frage.hiddenFrage}" />

ändert sich der Wert ja nie, da immer der gleiche Wert aus der Variable ausgelesen und ins Hidden geschrieben wird.

Oder hab ich da was falsch verstanden?

lg
 

JanHH

Top Contributor
Mh also du hast applikationsintern (irgendeine session scope bean) eine currentQuestin.

der getter für den hidden-parameter liest und kopiert sie

Java:
getExcpectedQuestion()
{
this.expectedQuestion=currentQuestion;
return excpetedQuestion;
}

setExceptedQuestion(String s)
{
excpetedQuestion=s;
}

und dann musst Du in der action-Methode nur vergleichen, ob currentQuestion und exceptedQuestion identisch sind.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Session ist nach Klick auf Zurück-Button wieder aktiv Web Tier 3
I Zurück Button mit JSF Command Button Web Tier 2
G Servlet getSession(false) in HttpServletRequest gibt nie null zurück Web Tier 3
B Zurück Funktion Web Tier 8
7 Struts vom popup wieder zurück ins alte Fenster? Web Tier 2
I Logout - Problem => Bei Zurück Web Tier 2
I Beim zurück-Link wird immer ein Request ausgeführt Web Tier 5
T Back Button bei JSF Anwendung Web Tier 2
S Button klick soll Java methode aufrufen Web Tier 2
Y Welcher Submit-Button wurde gedrückt? Web Tier 0
O JSF AccessKey auf Button-Beschriftung hervorheben Web Tier 0
G JSF Radio Button ValueChangeListener Wert wird nicht übernommen Web Tier 2
5 Button ID von betätigten Button herausfinden Web Tier 8
M JSF Button - Methode wird nicht aufgerufen Web Tier 4
M JSF Simple Testklasse für Button - MethodNotFoundException? Web Tier 6
J JSF Kein Methodenaufruf mit Button möglich durch PhaseListener (redirect) Problem? Web Tier 2
L in JSF ein download button erstellen Web Tier 4
B Mit JavaServlet Submit Button ermitteln Web Tier 5
T Button im Servlet - Werte übergeben Web Tier 2
K JSF: Tabelle; Button, Stringausgabe Web Tier 2
Tandibur JSF: Verlinkung mittels Button, bedingte Weiterleitung Web Tier 4
J location response-header? Browser-Back-Button "deaktivieren" Web Tier 9
MQue in JSP: "Drucken"- Button Web Tier 2
M Struts 2 Submit Button lokalisieren Web Tier 5
S Facelets Form: Validation abschalten bei Abbrechen-Button Web Tier 2
T Button abfrage mit Struts leicht gemacht ? Web Tier 3
A JSF: Button reagiert nicht und nicht verständliche Warnung Web Tier 6
G radio button deselect mit struts Web Tier 7
D JSF: Best Practice "Session invalidate nach Schließen des Browsers"? Web Tier 3

Ähnliche Java Themen

Neue Themen


Oben