corner imagecorner image
FeaturesPluginsDocs & SupportCommunityPartners

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, you created a simple web application called jAstrologer. You can download the project here if you have not run through the first installment.

So far the jAstrologer web application does the following:

  • Presents greeting.jsp, which uses two inputText components to ask for the user's name and birthday.
  • Saves the values entered by the user in the properties of the UserBean backing bean.
  • Reads the values of the properties from UserBean and displays them in success.jsp.

But was it really a success? In the application's present state, you do not know. The application takes any input (or no input at all) and calls it a success. That is why you need to add validation to the web application. In this tutorial you will do the following:

  • Make both inputText components required fields, which will automatically validate that something was input and show error messages if not.
  • Use a converter to convert the birthday inputText field into a java.util.Date object, which in itself checks that the data is a valid date.
  • Write some custom error messages to a new properties file, and improve their general display.
  • Create a custom validator to check whether input is in the form of a valid email address.

Contents

Content on this page applies to NetBeans IDE 6.x

To complete this tutorial, you need the following software and resources.

Software or Resource Version Required
NetBeans IDE version 6.x Java
Java Development Kit (JDK) version 5 or 6
GlassFish application server V2

Note: The GlassFish application server is optionally included in the Web and Java EE pack of NetBeans IDE.

Making a Field Required

The first thing you need to do is make sure that the user enters something for the name field. This is easily accomplished using the required attribute of the inputText component.

  1. Open greeting.jsp and change the name inputText component as follows (changes in bold):
    <p>Enter your name:
        <h:inputText value="#{UserBean.name}" id="name" required="true"/>
        <h:message for="name" style="color:red" /></p>
    You have just given an ID to the name text field, so you can later specify for which component the message displays. You then specified that the field is required, so the web application will show the error message if the user does not enter anything. Also, you set the font of the error message to display in red using the HTML style attribute. JSF tags generally accept all commonly used HTML attributes.
  2. In the Projects window, right-click the project node and choose Run (F6). The project is compiled and deployed to the server. Your default browser starts and opens greeting.jsp. Click Submit without entering a name. You get the following error:
    Error message displayed in browser when user submits without name input

Using a Converter

Consider treating the birthday field as a date and not a random string. The JSF framework provides a number of converters that you can use to convert text input into object types, such as booleans or Date objects. In the process of converting the data, the JSF framework also checks that the data is valid for the type of conversion selected. This is useful for the birthday input field because you can specify the date format, validate the input, and get a Date object all at once.

  1. Open greeting.jsp and change the birthday inputText component as follows (changes in bold):
    <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" style="color:red" /></p>
    You have just given an ID to the birthday text field, so you can then specify for which component the message is displayed. 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. You also specified that the field is required and set error text to red, as you previously did with the name field.

    Note: "MM" in the pattern dd/MM/yyyy signifies months whereas "mm" in a pattern dd/mm/yyyy would signify minutes. See the API for SimpleDateFormat for more details.
  2. You need to change the type of the birthday property in UserBean.java to a Date object. Open the UserBean class to make the following changes (in bold) and add an import statement for java.util.Date:
    package astrologer.user;
    
    import java.util.Date;
    
    public class UserBean {
        private String name;
        private Date birthday;
    
        /** Creates a new instance of UserBean */
        public UserBean() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
    }
    You can allow the IDE to add required import statements for you by right-clicking in the Source Editor and choosing Fix Imports (Ctrl-Shift-I; ⌘-Shift-I on Mac).
  3. Run the project. When you try to click Submit without entering a date, you get the following error message:
    Error message displayed in browser when user submits without birthday input

    If you enter a date in an unaccepted format, you get the following error:
    Error message displayed in browser when user submits birthday input in wrong format

Changing the Default Error Messages

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 from the Projects window by expanding Libraries > GlassFish V2 (or V3) > jsf-impl.jar > com.sun.faces.resources and double-clicking Messages.properties.

You can create custom messages for the previously displayed errors by replacing the properties file used by the application.

  1. In the Projects window, right-click the jAstrologer project node and choose New > Other. In the New File wizard that displays, select Properties File under the Other category, and click Next.
  2. In the Name and Location panel of the wizard, name the file MyMessages, type src/java/astrologer/ui for the Folder, and click Finish. MyMessages.properties opens in the Source Editor.
  3. Open the Files window (Ctrl-2) and expand the src/java/astrologer/ui folder to see the file listed.
  4. Copy over the following properties from Messages.properties to MyMessages.properties:
    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}
  5. Change the values of the properties:
    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}
  6. Open faces-config.xml (under Configuration Files in the Projects window). If necessary, click the XML tab in the toolbar above the Source Editor to view the file's code, and declare a new message bundle inside the faces-config element:
        <application>
            <message-bundle>astrologer.ui.MyMessages</message-bundle>
        </application>
    </faces-config>
  7. Right-click the project node and choose Run. When you do not enter anything for a required field or enter an unaccepted date format for the birthday field, the application shows the following errors:
    Customized rror messages displayed in browser
    Note that any messages that you have not specified in your custom properties file will be taken from the default Messages.properties in jsf-impl.jar.

Creating a Custom Validator

You can code your own validators if the standard JSF validators do not work for you. In this example, you 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, then register the class in faces-config.xml. You can then apply the validator using the f:validator tag.

  1. Right-click the project node and choose New > Java Class. Name the class EmailValidator, create a new package for it by typing in astrologer.validate in the Package field, and click Finish.
  2. In the newly created file, modify the class declaration to implement Validator as follows:
    public class EmailValidator implements Validator {
  3. Click on the light bulb icon that displays in the Source Editor's left column to display hints for adding the import statement and generating abstract methods:
    Import hint displayed in Source Editor
    Abstract methods hint displayed in Source Editor
  4. Modify the validate() method as follows:
    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);
        }
    }
  5. Right-click in the Source Editor and choose Fix Imports (Ctrl-Shift-I; ⌘-Shift-I on Mac) to add any necessary import statements. (You should choose to import java.util.regex.Matcher, java.util.regex.Pattern and javax.faces.application.FacesMessage.)
  6. Open faces-config.xml and add the following code (in bold):
        <application>
             <message-bundle>astrologer.ui.MyMessages </message-bundle>
        </application>
        <validator>
            <validator-id>astrologer.EmailValidator</validator-id>
            <validator-class>astrologer.validate.EmailValidator</validator-class>
        </validator>
    </faces-config>
  7. Open greeting.jsp and add a field for entering an email address:
    <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" style="color:red" /></p>
    
    <p>Enter your birthday:
  8. Run the project. When you enter an invalid email address in the field, you get the following error:
    Error message displayed in browser when an invalid email is entered

Creating a Custom Converter

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 does not check whether the date is in the past. To fine-tune how the date is checked, you can create a custom converter. The custom converter checks that the date is in the correct format and that it is in the past. If an error is encountered, the converter displays an 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 apply the converter by using the f:converter tag.

  1. Right-click the project node and choose New > Java Class. Name the class MyDateConverter, and create a new package for it by typing astrologer.convert in the Package field. Click Finish.
  2. In the class declaration, implement Converter as follows (changes in bold):
    public class MyDateConverter implements Converter {
  3. Use the IDE hints to add the appropriate import statement and implement abstract methods. (In the previous section you used IDE hints for this purpose.) The IDE generates two methods: getAsObject() and getAsString().
  4. Modify the getAsObject() method as follows:
    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 later than current date");
            message.setSummary("Date is later than current date");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ConverterException(message);
        }
        return nDate;
    }
  5. Make the following changes to the getAsString() method:
    public String getAsString(FacesContext facesContext, UIComponent uIComponent, Object value) {
        return value.toString();
    }
  6. Right-click in the Source Editor and choose Fix Imports (Ctrl-Shift-I; ⌘-Shift-I on Mac) to add the necessary import statements.
  7. Open faces-config.xml and add the following code:
        </validator>
        <converter>
            <converter-id>astrologer.MyDateConverter</converter-id>
            <converter-class>astrologer.convert.MyDateConverter</converter-class>
        </converter>
    </faces-config>
  8. Open greeting.jsp and modify the form to reference the custom converter you created:
    <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:red" /></p>
    
    <p>Enter your birthday:
        <h:inputText value="#{UserBean.birthday}" id="birthday" required="true">
            <f:converter converterId="astrologer.MyDateConverter" />
        </h:inputText> (dd/mm/yyyy)
        <h:message for="birthday" style="color:red" /></p>
    
        <h:commandButton value="Submit" action="submit" />
  9. Run the project. When you enter a future date in the birthday field, you see the following error:
    Error message displayed in browser when a future date is entered for birthday

Next Steps

This document described how to implement validation for user input in a web application. Specifically, it demonstrated how to make input fields required, and display error messages when input is lacking. It also showed how to use a converter to convert a string into a java.util.Date object, which checks if user input was received in the proper format. Finally, it demonstrated how to add custom validation to a backing bean.

See the official JavaServer Faces documentation for tutorials, FAQs and articles. The book, JSF: The Complete Reference, is a thorough guide on understanding the JavaServer Faces framework at a deep level. Also, the Java EE 5 Tutorial is a comprehensive resource for learning how to develop web applications. Refer to it for a more thorough description of custom validators and error messages, and more generally robust validation.

You can learn more by continuing to the third installment of the jAstrologer series of JSF tutorials:

For information about using other web frameworks in the NetBeans IDE, see the following resources: