当前页面: 开发资料首页 → Netbeans 专题 → Validating and Converting User Input With the JSF Framework
摘要: This document is the second installment in the jAstrologer series of JSF tutorials. In the first installment of the series, we created a simple web application called jAstrologer. You can download the project here if you have not run through the first installment. Make sure you undeploy any other applications with the /jAstrologer context root that you may have already deployed to the server
So far the jAstrologer web application does the following:
But was it really a success? In the present state, we don't know. We just take any input (or no input at all) and call it a success. That's why we need to build in a little validation to our web application. In this section we're going to do the following:
This document assumes you have some basic knowledge of, or programming experience with, the following technologies:
For this tutorial you need to have the following software installed on your computer:
For this tutorial you need to register a local instance of Sun Java System Application Server with the IDE.
The first thing we need to do is make sure that the user enters something for the name field. We can easily do this by using the required attribute of the inputText component.
<p>Enter your name: <h:inputText value="#{UserBean.name}" id="name" required="true"/> <h:message for="name" /></p>
What we have done is to give an ID to the name text field, so we can then specify for which component the message shows. We have then specified that the field is required, so the web application will show the error message if the user does not enter anything.
Now we need to start treating our birthday field as a date and not just a random string. The JSF framework provides a number of converters that you can use to convert text input into object types, like booleans and so forth. In the process of converting the data, it also checks that the data is valid for the type it's converting it into. This is especially handy for our birthday input field because we can specify the date format, validate the input, and get a nice Date object all at once.
<p>Enter your birthday: <h:inputText value="#{UserBean.birthday}" id="birthday" required="true"> <f:convertDateTime pattern="dd/MM/yyyy" /> </h:inputText> (dd/mm/yyyy) <h:message for="birthday" /></p>
What we have done is to give an id to the birthday text field, so we can then specify for which component the message is displayed. We have then set the converter to the pattern dd/MM/yyyy. Anything the user enters that does not match this format will cause the web application to redisplay greeting.jsp with an error message. We have also specified that the field is required, like we did with the name field.
private String name; private Date birthday; ... public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; }
If you enter an invalid date, you get the following error:
The error messages that are shown for each type of validation error are controlled by the Message.properties file, which is located in the javax.faces package of jsf-impl.jar. You can view this file by expanding Libraries > Sun Java System Application Server > jsf-impl.jar > javax.faces and double-clicking Messages.properties.
You can create custom messages for these errors by replacing the properties file used by the application.
javax.faces.component.UIInput.REQUIRED={0}: Validation Error: Value is required. javax.faces.converter.DateTimeConverter.DATE={2}: ''{0}'' could not be understood as a date. javax.faces.converter.DateTimeConverter.DATE_detail={2}: ''{0}'' could not be understood as a date. Example: {1}
javax.faces.component.UIInput.REQUIRED=Please enter a value for this field. javax.faces.converter.DateTimeConverter.DATE=Please enter a valid date. javax.faces.converter.DateTimeConverter.DATE_detail=Please enter a valid date. Example: {1}
... <application> <message-bundle>astrologer.ui.MyMessages</message-bundle> </application> </faces-config>
Note that any messages that you haven't specified in your custom properties file will be taken from the default Messages.properties in jsf-impl.jar. Also, you can define a CSS style for error messages and then specify that style in the message tag by doing the following:
<h:message for="birthday" style="color:#369;" /></p>
You can code your own validators if the standard JSF validators do not work for you. In our example, we will code a validator that checks a string to see if it is a valid email. To create a custom validator, you create a class that implements the javax.faces.validator.Validator interface and register the class in faces-config.xml. You can then use the validator using the <f:validator> tag.
public class EmailValidator implements Validator {
public void validate(FacesContext facesContext, UIComponent uIComponent, Object value) throws ValidatorException { //Get the component's contents and cast it to a String String enteredEmail = (String)value; //Set the email pattern string Pattern p = Pattern.compile(".+@.+\\.[a-z]+"); //Match the given string with the pattern Matcher m = p.matcher(enteredEmail); //Check whether match is found boolean matchFound = m.matches(); if (!matchFound) { FacesMessage message = new FacesMessage(); message.setDetail("Email not valid - The email must be in the format "); message.setSummary("Email not valid - The email must be in the format "); message.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(message); } }
... </application> <validator> <validator-id>astrologer.EmailValidator</validator-id> <validator-class>astrologer.validate.EmailValidator</validator-class> </validator> </faces-config>
... <p>Enter your name: <h:inputText value="#{UserBean.name}" id="name" required="true"/> <h:message for="name" /></p> <p>Enter your email: <h:inputText value="email" id="email" required="true"> <f:validator validatorId="astrologer.EmailValidator" /> </h:inputText> <h:message for="email" /></p> <p>Enter your birthday: <h:inputText value="#{UserBean.birthday}" id="birthday" required="true"> ...
Although performing validation using required fields and converters is easy, it is also very limited. For example, the converter checks that the birthday field is a valid date, but it doesn't check that the date was in the past. To fine-tune how the date is checked, we will create a custom converter. Our custom converter will check that the date is in the correct format and that it is in the past. If an error is encountered, the converter will display the appropriate message.
To create a custom converter, you create a class that implements the javax.faces.converter.Converter interface and then register the class in faces-config.xml. You can then use the converter using the <f:converter> tag.
public class MyDateConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException { String pattern = "dd/MM/yyyy"; SimpleDateFormat sdf = new SimpleDateFormat(pattern); Date nDate; try { nDate = sdf.parse(value); } catch (ParseException ex) { FacesMessage message = new FacesMessage(); message.setDetail("Date is missing or not valid"); message.setSummary("Date is missing or not valid"); message.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ConverterException(message); } if(nDate.getTime() > new Date().getTime()){ FacesMessage message = new FacesMessage(); message.setDetail("Date is bigger than current date"); message.setSummary("Date is bigger than current date"); message.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ConverterException(message); } return nDate; }
public String getAsString(FacesContext facesContext, UIComponent uIComponent, Object value) { return value.toString(); }
<converter> <converter-id>astrologer.MyDateConverter</converter-id> <converter-class>astrologer.convert.MyDateConverter</converter-class> </converter>
<p>Enter your name: <h:inputText value="#{UserBean.name}" id="name" required="true"/> <h:message for="name" style="color:#f00;" /></p> <p>Enter your email: <h:inputText value="#{UserBean.email}" id="email" required="true"> <f:validator validatorId="astrologer.EmailValidator" /> </h:inputText> <h:message for="email" style="color:#f00;" /></p> <p>Enter your birthday: <h:inputText value="#{UserBean.birthday}" id="birthday" required="true"> <f:converter converterId="astrologer.MyDateConverter" /> </h:inputText> <h:message for="birthday" style="color:#f00;" /> (dd/mm/yyyy)</p> <h:commandButton value="Submit" action="#{UserBean.submit}" />
And that's it. There are, of course, a lot of other ways you can handle validation. See the Java EE 5 Tutorial for a full description of custom validators, custom error messages, and more robust validation.