1. Overview
Java Enterprise Edition (JEE) 7 provides some useful features e.g. for validating user input, converting values into appropriate Java data types.
In this tutorial, we’ll focus on those features provided by converters, listeners, and validators.
2. Converters
A converter allows us to transform string input values into a Java data types. Predefined converters are located in the javax.faces.convert package, and they are compatible with any Java data type or even standard classes like Date.
To define an Integer converter, first we create our property in the managed bean used as a back end of our JSF form:
private Integer age;
// getters and setters
Then we create the component in our form using the f:converter tag:
<h:outputLabel value="Age:"/>
<h:inputText id="Age" value="#{convListVal.age}">
<f:converter converterId="javax.faces.Integer" />
</h:inputText>
<h:message for="Age" />
In a similar way, we create the other numeric converters like the Double converter:
private Double average;
Then we create the appropriate JSF component in our view. Please note that we are using the variable average, which is then mapped to the field using the getter and the setter by name convention:
<h:outputLabel value="Average:"/>
<h:inputText id="Average" value="#{convListVal.average}">
<f:converter converterId="javax.faces.Double" />
</h:inputText>
<h:message for="Average" />
If we want to give the feedback to the user, we need to include an h:message tag to be used by the control as a placeholder for error messages.
A useful converter is the DateTime converter because it allows us to validate dates, times and format these values.
First, as in previous converters, we declare our field with the getters and setters:
private Date myDate;
// getters and setters
Then we create the component in our view. Here we need to enter the date using the pattern, if the pattern is not used then we get an error with an example of a correct pattern of the input:
<h:outputLabel value="Date:"/>
<h:inputText id="MyDate" value="#{convListVal.myDate}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="MyDate" />
<h:outputText value="#{convListVal.myDate}">
<f:convertDateTime dateStyle="full" locale="en"/>
</h:outputText>
In our case, we can convert our input date and send the post data, formatted as a full date in our h:outputText.
3. Listeners
A listener allows us to monitor changes in our components; we are monitoring when the value of a text field changes.
As before we define the properties in our managed bean:
private String name;
Then we define our listener in the view:
<h:outputLabel value="Name:"/>
<h:inputText id="name" size="30" value="#{convListVal.name}">
<f:valueChangeListener type="com.baeldung.convListVal.MyListener" />
</h:inputText>
We set our h:inputText tag by adding an f:valueChangeListener and also, inside the listener tag, we need to specify a class, which will be used to perform the tasks when the listener is triggered.
public class MyListener implements ValueChangeListener {
private static final Logger LOG = Logger.getLogger(MyListener.class.getName());
@Override
public void processValueChange(ValueChangeEvent event)
throws AbortProcessingException {
if (event.getNewValue() != null) {
LOG.log(Level.INFO, "\tNew Value:{0}", event.getNewValue());
}
}
}
The listener class must implement the ValueChangeListener interface and override the processValueChange() method to do the listener tasks, to write a log message.
4. Validators
We use a validator to validate a JSF component data, with a set of standard classes provided, to validate the user input.
Here, we defined a standard validator to enable us to check the length of a user input in a text field.
First, we create our field in the managed bean:
private String surname;
Then we create our component in the view:
<h:outputLabel value="surname" for="surname"/>
<h:panelGroup>
<h:inputText id="surname" value="#{convListVal.surname}">
<f:validateLength minimum="5" maximum="10"/>
</h:inputText>
<h:message for="surname" errorStyle="color:red" />
</h:panelGroup>
Inside the h:inputText tag we put our validator, to validate the length of the input. Please remember that there are various standard validators predefined in JSF and we can use them in a similar way to the one presented here.
5. Tests
To test this JSF application, we are going to use Arquillian to perform a functional testing with Drone, Graphene and Selenium Web Driver.
First, we deploy our application using ShrinkWrap:
@Deployment(testable = false)
public static WebArchive createDeployment() {
return (ShrinkWrap.create(
WebArchive.class, "jee7.war").
addClasses(ConvListVal.class, MyListener.class)).
addAsWebResource(new File(WEBAPP_SRC, "ConvListVal.xhtml")).
addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
Then we test the error messages of each component to verify that our application is working properly:
@Test
@RunAsClient
public void givenAge_whenAgeInvalid_thenErrorMessage() throws Exception {
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
ageInput.sendKeys("stringage");
guardHttp(sendButton).click();
assertTrue("Show Age error message",
browser.findElements(By.id("myForm:ageError")).size() > 0);
}
Similar tests are performed on each component.
6. Summary
In this tutorial, we created implementations of converters, listeners, and validators provided by JEE7.
You can find the code from the article over on Github.