JSF converters convert String to Java Object (typically managed beans properties) and vice-versa. A converter class needs to implement javax.faces.convert.Converter interface.
This example demonstrates how to create and register a custom JSF converter.
Example
A Java Object
public class Phone {
private String areaCode;
private String exchangeCode;
private String lineNumber;
.............
}
The Converter
@FacesConverter(forClass = Phone.class)
public class PhoneConverter implements Converter {
private static final Pattern PHONE_PATTERN = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Matcher matcher = PHONE_PATTERN.matcher(value);
if (!matcher.matches()) {
throw new RuntimeException(
String.format("invalid input: %s. The valid format is of type %s%n",
value, "111-111-1111"));
}
String areaCode = matcher.group(1);
String exchange = matcher.group(2);
String line = matcher.group(3);
return new Phone(areaCode, exchange, line);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
Phone phone = (Phone) value;
return String.format("%s-%s-%s",
phone.getAreaCode(), phone.getExchangeCode(), phone.getLineNumber());
}
}
The forClass attribute registers the converter by the provided type. Therefore, whenever the target type is used with an input component, the converter is invoked automatically.
JSF page
src/main/webapp/index.xhtml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head></h:head>
<h:body>
<h2>JSF custom converter example</h2>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel for="ph" value="Phone: "/>
<h:inputText id="ph" value="#{phoneBean.phone}">
</h:inputText>
<h:commandButton value="Submit" action="result.xhtml"/>
</h:panelGrid>
<div>
phone:
<h:outputText value = "#{phoneBean.phone}"/>
</div>
</h:form>
</h:body>
</html>
Managed Bean
@ManagedBean
@ViewScoped
public class PhoneBean {
private Phone phone;
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
}
To try examples, run embedded tomcat (configured in pom.xml of example project below):
mvn tomcat7:run-war
Output
On entering and submitting a valid phone number:
Registering and referencing a converter by its id
Instead of using forClass attribute , we can create the converter by defining its id and then use it's reference in the views.
@FacesConverter("phConverter")
public class PhoneConverter implements Converter {
...
}
Using converter attribute
<h:form>
<h:panelGrid columns="2">
<h:outputLabel for="ph" value="Phone: "/>
<h:inputText id="ph" value="#{phoneBean.phone}" converter="phConverter">
</h:inputText>
<h:commandButton value="Submit" action="result.xhtml"/>
</h:panelGrid>
<div>
phone:
<h:outputText value = "#{phoneBean.phone}" converter="phConverter"/>
</div>
</h:form>
Using <f:converter />
<h:form>
<h:panelGrid columns="2">
<h:outputLabel for="ph" value="Phone: "/>
<h:inputText id="ph" value="#{phoneBean.phone}">
<f:converter converterId="phConverter"/>
</h:inputText>
<h:commandButton value="Submit" action="result.xhtml"/>
</h:panelGrid>
<div>
phone:
<h:outputText value = "#{phoneBean.phone}">
<f:converter converterId="phConverter"/>
</h:outputText>
</div>
</h:form>
Example ProjectDependencies and Technologies Used: - jsf-api 2.2.14:
This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
- jsf-impl 2.2.14:
This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
- JDK 1.8
- Maven 3.3.9
|