Latest Entries »

Thursday, November 5, 2009

Konwersja i weryfikacja przy pomocy standardowych kontrolek JSF

Nadszedł czas omówić konwersję i weryfikację danych w aplikacji JavaServer Faces przy użyciu standardowych mechanizmów przygotowanych przez twórców JSF. Przykład ten będzie na tyle prosty aby każdy mógł zrozumieć naturę standardowych mechanizmów kontroli wpisywanych danych przez użytkownika, a następnie pozwoli nam utworzyć własne klasy implementujące odpowiednie interfejsy. No to zaczynamy:

1) Utwórzmy formularz, który będzie zawierać następujące pola tekstowe:

Za informację przechowywane w każdym polu będzie odpowiadać klasa RegistrationForm:

public class RegistrationForm {
private String name;
private String surname;
private Date dateOfBirth;
private int age;
private double doubleValue;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSurname() {
return surname;
}

public void setSurname(String surname) {
this.surname = surname;
}


public Date getDateOfBirth() {
return dateOfBirth;
}

public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public double getDoubleValue() {
return doubleValue;
}

public void setDoubleValue(double doubleValue) {
this.doubleValue = doubleValue;
}

}
Natomiast nasz kod strony powinien na początku wyglądać następująco:

<h:form prependId="false">
<table>
<tr>
<td>Imię:</td>
<td><ice:inputText id="name" value="#{registrationForm.name}" >
</ice:inputText></td>
<td></td>
</tr>
<tr>
<td>Nazwisko:</td>
<td><ice:inputText id="surname" value="#{registrationForm.surname}" >
</ice:inputText></td>
<td></td>
</tr>
<tr>
<td>Data urodzenia:</td>
<td>
<ice:selectInputDate id="dateOfBirth"
value="#{registrationForm.dateOfBirth}">
</ice:selectInputDate> </td>
<td></td>
</tr>
<tr>
<td>Wiek:</td>
<td><ice:inputText id="age" value="#{registrationForm.age}" >
</ice:inputText></td>
<td></td>
</tr>
<tr>
<td>Wartość double:</td>
<td><ice:inputText id="doubleValue" value="#{registrationForm.doubleValue}">
</ice:inputText></td>
<td></td>
</tr>
</table>
</h:form>

<ice:commandButton value="Dalej" action="registration"/>
Teraz utwórzmy drugą stronę RegistrationComplete.jspx i utwórzmy w pliku faces-config.xml regułę nawigacji pomiędzy obiema stronami.
Strona RegistrationComplete.jspx:

<jsp:root version="2.1"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ice="http://www.icesoft.com/icefaces/component">
<jsp:directive.page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"/>
<f:view>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>RegistrationComplete.jspx</title>
</head>
<body>
<h1>Dziękujemy za rejestrację!</h1>
<ice:form>

</ice:form>
</body>
</html>
</f:view>
</jsp:root>
Reguła nawigacji:

<navigation-rule>
<from-view-id>/robpie/RegistrationFormIFaces.jspx</from-view-id>
<navigation-case>
<from-outcome>registration</from-outcome>
<to-view-id>/robpie/RegistrationComplete.jspx</to-view-id>
</navigation-case>
</navigation-rule>
Czas na przetestowanie czy reguła nawigacji działa. Uruchamiamy projekt i przechodzimy na stronę: RegistrationFormIFaces.jspx i klikamy przycisk "Dalej". Powinniśmy ujrzeć drugą stronę.

Weryfikacja i konwersja.

Każda kontrolka posiada atrybut required, który oznacza czy pole jest wymagane. np:

<ice:inputText id="name" value="#{registrationForm.name}" required="true">
</ice:inputText>
<ice:inputText id="age" value="#{registrationForm.age}" > </ice:inputText>
Oznacza to, że jeśli nie uzupełnimy danego pola to nie będziemy mogli przejść na drugą stronę. Teraz dodajmy jeszcze jeden znacznik, który poinformuje nas o napotkanych błędach ponieważ standardowo błędy tego typu nie są wyświetlane na stronie (Wyświetlają się w logach serwera Glassfish). W każdy wolny znacznik wstawmy następujący kod:


<ice:message for="name" />
<ice:message for="surname" />
<ice:message for="dateOfBirth" />
<ice:message for="age" />
<ice:message for="doubleValue" />


Atrybut for lokalizuje nam dla jakiego identyfikatora id kontrolki wejściowej ma wyświetlać błędy.
Teraz nasza strona powinna wyglądać następująco:


<h:form prependId="false">
<table>
<tr>
<td>Imię:</td>
<td><ice:inputText id="name" value="#{registrationForm.name}" required="true">
</ice:inputText></td>
<td><ice:message for="name" /></td>
</tr>
<tr>
<td>Nazwisko:</td>
<td><ice:inputText id="surname" value="#{registrationForm.surname}" required="true">
</ice:inputText></td>
<td><ice:message for="surname" /></td>
</tr>
<tr>
<td>Data urodzenia:</td>
<td>
<ice:selectInputDate id="dateOfBirth"
value="#{registrationForm.dateOfBirth}"
required="true">
</ice:selectInputDate> </td>
<td><ice:message for="dateOfBirth" /></td>
</tr>
<tr>
<td>Wiek:</td>
<td><ice:inputText id="age" value="#{registrationForm.age}" >
</ice:inputText></td>
<td><ice:message for="age" /></td>
</tr>
<tr>
<td>Wartość double:</td>
<td><ice:inputText id="doubleValue" value="#{registrationForm.doubleValue}">
</ice:inputText></td>
<td><ice:message for="doubleValue" /></td>
</tr>
</table>
<ice:commandButton value="Dalej" action="registration"/>
</h:form>
W tym momencie czas przetestować naszą aplikację. Uruchamiamy ją i przechodzimy na stronę z rejestracją. Klikamy "Dalej". Widać, że w tym momencie wyświetlają się pewne komunikaty, które informują, że pole jest wymagane.
Validation Error: Value is required.

Teraz dodamy kolejne validatory, a na końcu pokażę jak zmienić standardowe komunikaty frameworku JavaServer Faces.
Dodamy:


<f:validateLength minimum="5" maximum="20" />
<f:convertDateTime pattern="dd/MM/yyyy" />
<f:validateLongRange minimum="18" maximum="98" />
<f:validateDoubleRange minimum="3.14" maximum="18.5" />

1)Weryfikacja długości łańcucha znakowego.
2)Konwersja łańcucha znakowego na typ Date po stronie serwera.
3)Weryfikacja przedziału liczb całkowitoliczbowych.
4)Weryfikacja przedziałów liczb zmiennoprzecinkowych.
Odpowiednie kontrolki dodajmy między znaczniki inputText i selectInputDate:



<ice:inputText id="name" value="#{registrationForm.name}" required="true">
<f:validateLength minimum="5" maximum="20" />
</ice:inputText>
<ice:inputText id="surname" value="#{registrationForm.surname}" required="true">
<f:validateLength minimum="5" maximum="20" />
</ice:inputText>
<ice:selectInputDate id="dateOfBirth"
value="#{registrationForm.dateOfBirth}"
renderAsPopup="true"
required="true">
<f:convertDateTime pattern="dd/MM/yyyy" />
</ice:selectInputDate>
<ice:inputText id="age" value="#{registrationForm.age}" >
<f:validateLongRange minimum="18" maximum="98" />
</ice:inputText>
<ice:inputText id="doubleValue" value="#{registrationForm.doubleValue}">
<f:validateDoubleRange minimum="3.14" maximum="18.5" />
</ice:inputText>
Zwiększyliśmy restrykcje weryfikacji i nieporawne dane zostają wykryte a odpowiednie błędy są wyświetlane.
Powinniśmy teraz zmienić treść każdego z błędów na taki, który nam odpowiada.
Zaletą JSF jest to, że wszystkie komunikaty przechowywujemy w jednym miejscu. Każdy komunikat jest zmienną odpowiedniej klasy. Raz zdefiniowane błędy będą dostępne w każdym formularzu i na każdej stronie. W przeciwieństwie do ASP.NET nie musimy klepać wszędzie errorMessage w każdym miejscu.
Musimy utworzyć odpowiedni plik np:
myMessage.properties i tam umieścić nasze komunikaty:
Klikamy na swoją paczkę PPM wybieramy New -> Other -> Other -> Properties File.
Klikamy PPM na plik myMessages.properties i klikamy Edit.
Wklejamy następujący kod:



javax.faces.component.UIInput.REQUIRED=<b><span >*Pole {0} obowiązkowe.</span></b>
javax.faces.validator.LongRangeValidator.NOT_IN_RANGE=<b><span style="color:red">*Wartość {2} musi być w przedziale od {0} do {1}.</span></b>
javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE=<b><span >*Wartość {2} musi być w przedziale od {0} do {1}.</span></b>
javax.faces.converter.DateTimeConverter.CONVERTER=Please enter a valid date.
javax.faces.converter.DateTimeConverter.DATE=<b><span >Podaj poprawny format daty: {1}</span></b>
javax.faces.component.UIInput.CONVERSION=<b><span style="color:red">*Błąd konwersji.</span></b>
javax.faces.validator.LengthValidator.MINIMUM=<b><span >*Pole {1} musi być większe od {0}</span></b>
javax.faces.validator.LengthValidator.MAXIMUM=<b><span style="color:red">*Pole {1} musi być mniejsze od {0}</span></b>

Ostatnim krokiem będzie dodanie odpowiedniego wpisu do pliku faces-config.xml informującego gdzie framework ma szukać pliku z komunikatami.

Uruchamiamy aplikację i testujemy działanie.



<application>
<message-bundle>robpie.myproperties</message-bundle>
</application>

0 comments:

Post a Comment