站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Netbeans 专题Validating and Converting User Input With the JSF Framework

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:

Prerequisites

This document assumes you have some basic knowledge of, or programming experience with, the following technologies:

Software Needed for the Tutorial

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.

Tutorial Exercises

Making a Field Required

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.

  1. Open greeting.jsp and change the name inputText component as follows:
    <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.

  2. Run the project and click Submit without entering a name. You get the following error:

    no name error

Using a Converter

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.

  1. Open greeting.jsp and change the birthday inputText component as follows:
            <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.

  2. Now we need to change the type of the birthday property in UserBean.java to a Date object. Open UserBean.java and make the following changes in bold and add an import statement to import java.util.Date:
        private String name;
        private Date birthday;
        ...
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }    
  3. Run the project. When you try to click Submit without entering a date, you get the following error message:

    screenshot of error message displayed in browser when no date is entered

    If you enter an invalid date, you get the following error:

    screenshot of error message displayed in browser when an invalid date is entered

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 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.

  1. Right-click the jAstrologer project and choose New > File/Folder. Under the Other category, select Properties File and click Next. Name the file MyMessages, type src/java/astrologer/ui for the Folder, and click Finish. MyMessages.properties opens in the Source Editor. In the Files window, expand the src/java/astrologer/ui folder to see the file.
  2. 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}
  3. 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}
  4. Open faces-config.xml (under the Configuration Files node in the Projects window) and enter the following inside the main faces-config element:
        ...
        <application>
            <message-bundle>astrologer.ui.MyMessages</message-bundle>
        </application>
    </faces-config>
  5. Right-click the application and choose Run Project. When you do not enter anything for a required field or enter a bad date format for the birthday field, the application now shows the following errors:

    custom errors

    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>

Creating a Custom Validator

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.

  1. Right-click the project node and choose New > Java Class. Name the class EmailValidator, place it in the astrologer.validate package, and click Finish.
  2. In the class declaration, implement Validator as follows:
    public class EmailValidator implements Validator {
  3. Use the hint to implement the validate method.

    screenshot of IDE hint feature displayed in Source Editor

  4. Modify the method signature and add the following code to the validate method:
        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. Press Alt+Shift+F 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:
         ...
        </application>
        <validator>
            <validator-id>astrologer.EmailValidator</validator-id>
            <validator-class>astrologer.validate.EmailValidator</validator-class>
        </validator>
    </faces-config>
  7. Open greeting.jsp and add the email field:
         ...
            <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">
         ...
  8. Run the project. When you enter a non-valid email in the field, you get the following error:

    screenshot of error message displayed in browser when a non-valid 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 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.

  1. Right-click the project node and choose New > Java Class. Name the class MyDateConverter, place it in the astrologer.convert package, and click Finish.
  2. In the class declaration, implement Converter as follows (changes in bold):
     public class MyDateConverter implements Converter {
  3. Use the IDE hint to add the appropriate import statement and to implement the abstract methods. (In the previous section, you used the IDE hint to implement the validate method). The IDE generates two methods: getAsObject and getAsString.
  4. Add the following code to the getAsObject method (Be sure to change the String parameter in the method signature to value):
    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;
        }
  5. Modify the method signature and add the following to the getAsString method (In the method signature, be sure to change the name of the Object parameter to value):
    public String getAsString(FacesContext facesContext, UIComponent uIComponent, Object value) {
        return value.toString();
    }
  6. Press Alt+Shift+F to add any necessary import statements. (You should choose to import java.text.ParseException and java.util.Date.)
  7. Open faces-config.xml and add the following code:
    <converter>
       <converter-id>astrologer.MyDateConverter</converter-id>
       <converter-class>astrologer.convert.MyDateConverter</converter-class>
    </converter>
       
  8. Open greeting.jsp and update the form:
    <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}" />
    
        
  9. Run the project. When you enter a non-valid or future birthday date in the field, you get the following errors:

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.




↑返回目录
前一篇: Web Services (JAX-WS) in Java EE 5
后一篇: Using the File Upload Component