JSF/Facelets - Fehlermeldung ausgeben

Status
Nicht offen für weitere Antworten.
B

berndt

Gast
Hallo!

Ich habe nur eine kleine Frage, deren Lösung sich mir gerade nicht erschliesen will.

Und war habe ich ein simples Eingabeformular. Man gibt eine Antwort ein, klickt auf den Submit-Button, die Methode mybean.antwortsenden liest die getter-Variable von getAntworttext() aus, ermittelt was drin steht, und wenn die Antwort ok ist, soll weitergeleitet werden indem der String "weiter" zurückgeliefert wird.

Meine Frage nun, wie schaffe ich es, dass wenn die eingegebene Antwort falsch war, dieselbe Seite neu geladen wird und ein selbst definierter Fehlermeldungstext unter dem Eingabefeld erscheint? Habs bisher so gemacht das wenn die Antwort falsch ist, der String "fehler" zurückgeliefert worden ist.

Code:
<h:inputText id="antwort" value="#{mybean.anworttext}"/> 

<h:message for="antwort"  /> 

<h:commandButton value="Antwort senden" action="#{mybean.antwortsenden}"/>

Code:
    <navigation-rule>
        <description>
            Startseite
        </description>
        <from-view-id>/start.xhtml</from-view-id>
        <navigation-case>
            <description>
                von Startseite zu Ergebnisseite
            </description>
            <from-outcome>weiter</from-outcome>
            <to-view-id>/ergebnis.xhtml</to-view-id>
        </navigation-case>
        <navigation-case>
            <description>
                Fehlerhafte Antwort
            </description>
            <from-outcome>fehler</from-outcome>
            <to-view-id>/start.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
 

WeirdAl

Bekanntes Mitglied
Hi,
dazu gibts die Validatoren. Hier mal als Beispiel einen Validator der die Eingabe eines Nutzernamens bei dem registrieren prüft (nach dem submit in einer form):

Code:
<h:outputText value="Username:" /> 
					<h:inputText id="userName" value="#{registerBean.userName}" 
						validator="#{registerBean.validateUserName}" required="true">
					</h:inputText>

Und hier der Validator in dem Bean:



Code:
public void validateUserName(FacesContext context,
			 UIComponent componentToValidate,
			 Object value) 
			 throws ValidatorException {
				
		// Object value ist der String im InputText


		// prüfe ob User vorhanden ist wenn ja dann gebe eine Fehlermeldung aus:
			FacesMessage message = new FacesMessage(User existiert bereits"));
			throw new ValidatorException(message);
				
	}

Diese faceMessage erscheint dann im Bereich <h:messages> oder <h:message for...>. Ich hoffe das hilft dir weiter


Cu
Alex
 
B

berndt

Gast
Vielen Dank für die Antwort Alex. :)

So wie es aussieht funktioniert es mit dem Validator nicht. Ich muss die Überprüfung in "mybean.antwortsenden" erledigen, da ich dort noch auf die getter einiger anderer Input-Felder zugreifen muss. Habe ich leider vergessen zu erwähnen.
Von einer Validator-Methode aus, kann ich leider nicht auf die getter der anderen Variablen zugreifen, da diese noch nicht gesetzt worden sind.

Stell dir einfach vor, es sind 2 Eingabefelder vorhanden. Beide müssen in einer Methode (antwortsenden) miteinander verglichen werden und je nach Ergebnis wird dann entweder "weiter" zurückgesendet, oder aber eine Fehlermeldung welche dann angezeigt werden soll.

Eine Idee wie ich das lösen kann?
 

WeirdAl

Bekanntes Mitglied
Hi,
nee das geht schon in einem Validator. Stell Dir vor neben dem UserName hast Du noch eine Emailadresse. Du musst nun überprüfen, ob Username UND Emailadresse vorhanden sind. Dazu bindest Du Dir zb. die Emailadresse auf UIInput BeanInput im Bean.

Hier mal ein Snippet als Beispiel, wo ich Username und Passwort bei meinem Login überprüfe:

Code:
private UIInput loginInput;
	private UIInput pwInput;
	
	public AuthenticBean() {
	}
	
	/**
	 * checks if user exists
	 * if not throw a Message
	 */
	public void validateLogin(FacesContext context,
							 UIComponent componentToValidate,
							 Object value) 
							 throws ValidatorException {
		
		String login2check = loginInput.getLocalValue().toString();
		String pw2check = value.toString();
		
			
			switch (UserRegistry.isUserReg(login2check, pw2check)) {
			// no user found
			case -1:{
				FacesMessage message = new FacesMessage(this.getMessageBundle().
														getString("AuthenticBean.noUserFound"));
				throw new ValidatorException(message);
				}
			// pw wrong
//login wrong
...
			default:
				break;
			}
	}
 
B

berndt

Gast
Hättest du mir noch den dazugehörigen JSF-Code? Bekomme das leider nicht so ganz hin. :(

Vielen Dank! :)
 

WeirdAl

Bekanntes Mitglied
Sischa Sischa :)

Hier der JSF Teil:
Code:
...
		
	    	<h:form id="loginForm">	
				<h:panelGrid styleClass="panelGrid" id="loginPanelGrid" columns="2" >
					<h:outputText id="loginText" value="Login:" />
					<h:inputText id="userLogin" size="8" binding="#{authenticBean.loginInput}" required="true"/>
					<h:outputText id="pwText" value="Pass:" />
					<h:inputSecret id="PW" required="true" size="8" 
						binding="#{authenticBean.pwInput}" validator="#{authenticBean.validateLogin}" />
					<h:commandButton id="loginButton" action="#{authenticBean.login}" 
						value="#{webContentBundle['button.login']}"/>
				</h:panelGrid>
			</h:form>
	...
 
B

berndt

Gast
Nach einigen Anpassungen hat es nun wunderbar geklappt. Vielen Dank für die Hilfe Alex.

Kannst du mir vielleicht noch erklären was genau da nun passiert ist? Ich vermute mal das während der Validierung mittels der Befehle

Code:
String login2check = loginInput.getLocalValue().toString(); 
String pw2check = value.toString();

die UI-Elemente aus dem Komponentenbaum ausgelesen worden sind, da zu diesem Zeitpunkt die Variablen der Bean noch nicht gesetzt werden.
 

WeirdAl

Bekanntes Mitglied
Hi,
jo mit UIInput kannst Du auf das gebundene Inputfeld im Komponentenbaum direkt zugreifen. Dies geht für jedes JSF-Element im Komponentenbaum. Da zu dem Zeitpunkt der Validierung die Werte in der Bean noch nicht gesetzt wurden (wie Du bereits selbst gesagt hast) musst Du über den Komponentenbaum auf die Felder/Properties, die nicht das value-Objekt sind, zugreifen. Wieso man jetzt genau mit getLocalValue an das Objekt kommt kann ich Dir nicht 100%ig sagen, da ich mir die API dazu nicht angsehen habe :) (ich habs blind aus einem Buch übernommen)

Cu
Alex
 
B

berndt

Gast
Danke! Und wieso wird hier Bindung benutzt, anstatt einfach "value"?

Code:
<h:inputText id="userLogin" size="8" binding="#{authenticBean.loginInput}" required="true"/>
 

WeirdAl

Bekanntes Mitglied
Weil value vom Typ String und binding vom Typ UIComponent ist. Hier in der Komponentenliste findest Du eine Übersicht der Unterklassen von UIComponent. (Die Liste ist zwar von der 1.1 Api, aber da dürfte sich in 1.2 nichts geändert haben)

Edit: Ah ich glaub jetzt weiss ich was Du meinst: Ich habe hier kein value genutzt, da ich die Logindaten nur prüfe und nicht weiterverarbeite. Daher hole ich mir die Werte von login und pw via binding und brauche kein String Login, pw. (Das spart mir auch getter/setter von den zwei Strings).
Wobei ich der Lesbarkeit halber mittlerweile nur noch dort Bindings nutze, wo ich sie zum validieren oder selektieren, zb von Tabellenreihen, benötige.

Cu
Alex
 
B

berndt

Gast
Ich hab in einem Buch gelesen das man für Bindings eigene Backing Beans benutzen und es vermeiden soll diese mit Managed Beans zu vermischen.

Also hätte dein Code auch funktioniert wenn man statt bindings einfach nur normale values mit setter und getter benutzt hätte?
 

WeirdAl

Bekanntes Mitglied
Hi,
Normal "sollte" man für eine View eine Bean benutzen. Es würde nicht mit values gehen, da man nur mit den Bindings an die zu prüfenden Werte kommt, da sie ja noch nicht in der Bean "eingetragen" wurden.


Ich hab in einem Buch gelesen das man für Bindings eigene Backing Beans benutzen und es vermeiden soll diese mit Managed Beans zu vermischen.
Welches Buch war denn das? :)
Managed Beans sind "nur" Instanzen von Backing Beans und wenn man z.B. Bindings und Strings nebst gettern/settern splittet, würde man somit nur zwei Managed Beans für eine View erstellen. (Link dazu)

Cu
Alex
 

Bluevelvet64

Aktives Mitglied
Hallo


habe ein ähnliches Problem und habe mich an Deiner Lösung orientiert.

Aber ich bekomme nur folgende fehlermedlung :

27.12.2007 22:26:39 com.sun.faces.lifecycle.LifecycleImpl phase
WARNUNG: executePhase(RENDER_RESPONSE 6,com.sun.faces.context.FacesContextImpl@147a87e) threw exception
javax.faces.FacesException: org.apache.jasper.JasperException: An exception occurred processing JSP page /pages/login/login.jsp at line 13

10: <DIV class="loginbox">
11: <DIV class="textueber">Privatkunden</DIV>
12: <DIV class="textbox">Name</div>
13: <DIV class="inputbox"><h:inputText binding="#{Login.priv_name}"/></div>
14: <DIV class="textbox">Passwort</div>
15: <DIV class="inputbox"><h:inputSecret binding="#{Login.priv_pass}" /></div>
16: <DIV class="buttonbox"><h:commandButton id="login_priv" actionListener="#{Login.check_login}" value="Anmelden"/></div>

Login ist in der faces-config mit Bean.LoginBean verbunden.

Den Quellcode aus der JSP siehst Du ja in der fehlermeldung. Hier ist der Code aus der bean

public class LoginBean
{
private UIInput priv_name;
private UIInput priv_pass;

public void check_priv(FacesContext context, UIComponent input, Object value) throws ValidatorException
{
... ...
}

public void check_login(ActionEvent event)
{

if(...)
{
.....
}

}

}

Ich vermute das die Komponente priv_name nicht gefunden wird weil das Objekt private ist. ( Auch netBeans zeigt mir über die Erweiterung das Objekt priv_name nicht an). Wenn ich das ganze über value binde, und eine getter und setter methode einbaue ( für eine String komponente ) funktioniert es. ( getter und setter sind ja public ) Ebenso wird die check_priv Methode nicht gefunden. Der ActionListener den ich auch in der bean verwende wird gefunden. Beide die Validator und die AcktionListener methode sind public. Warum finde ich zwar den ActionListener aber nicht den Validator. Und warum wird das UIInput Element nicht gefunden, wohl aber eine getter methode.

Leider geben auch die Bücher die ich verwende, hier keine richtige Auskunft.

Danke für eine Auskunft.
 
G

Gast

Gast
Hallo

ich glaube du müsstest Dich an die Namens-Konventionen halten.

priv_name und priv_pass und check_login folgen nicht ganz dieser Konvention. Die Setter und Getter könnten die Ursache des Problems sein ... Besser wäre

privName und privPass und checkLogin

bin aber nicht sicher ob Deine Fehler dann verschwinden.

Gruss
C
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M JSF JSP, Facelets und einbinden einer js-Datei Web Tier 2
W JSF Facelets integriert in JSF ? Web Tier 44
M Tobago und Facelets Web Tier 5
J Facelets javascript compiler problem Web Tier 3
ruutaiokwu jstl-basierendes tag in jsf 2.0. facelets/xhtml? Web Tier 5
D JSF Ajax mit Facelets (PrimeFaces) Web Tier 4
ruutaiokwu facelets content-type... Web Tier 5
ruutaiokwu jsf facelets mit xhtml strict 1.0 Web Tier 2
Y Facelets Dependency gesucht Web Tier 2
T JSF/Facelets mit Seam-Framework Web Tier 7
MrWhite Facelets: Dynamische Attribute Web Tier 3
R JSF Custom Tags + Facelets Web Tier 2
S Facelets Form: Validation abschalten bei Abbrechen-Button Web Tier 2
A JSTL Tags funktionieren nicht in Facelets/MyFaces Web Tier 3
eskimo328 dynamische Navigaiton und JSF (facelets) Web Tier 6
N Nixsagende Fehlermeldung bei EL-Funktion Web Tier 2
F Faclets Fehlermeldung Web Tier 4
H JSF Fehlermeldung Target Unreacheable Web Tier 3
H servlet fehlermeldung Web Tier 3
K "No source code is available"-Fehlermeldung mit EMF-Modell bei GWT Web Tier 2
G Fehlermeldung JSP Web Tier 2
S unerklärliche Fehlermeldung Web Tier 4
R Servlet Alle Parameter ausgeben Web Tier 14
N JSF Text formatiert ausgeben Web Tier 3
R Bild aus Datenbank ausgeben/anzeigen Web Tier 5
N Struts 1.1 - Arraylist einzelnes Element ausgeben - Sessionattribute weitergeben Web Tier 3
J JSF List ausgeben Web Tier 6
D Anzahl Objekte in Liste in JSF ausgeben. Web Tier 2
A PDF als ByteArrayOutputStream in JSP ausgeben Web Tier 5
J Servlet soll XML ausgeben und Javascript soll dieses einlesen Web Tier 3
T Einfach nur Daten im JSP ausgeben Web Tier 2
K Jsp als Pdf ausgeben Web Tier 3
S nur eine Message auf Faceskontext ausgeben Web Tier 2
T Liste nach Anfangsbuchstaben getrennt ausgeben? Web Tier 2
S richfaces Datatable horizontal ausgeben Web Tier 2
N Info bei Start von WebApp ausgeben Web Tier 8
G Mit JSTL Rückgabe von Bean Methode ausgeben Web Tier 3

Ähnliche Java Themen

Neue Themen


Oben