In this article, we show you how to create a custom converter in JSF 2.0.

Steps
1. Create a converter class by implementing javax.faces.convert.Converter interface.
2. Override both getAsObject() and getAsString() methods.
3. Assign an unique converter ID with @FacesConverter annotation.
4. Link your custom converter class to JSF component via f:converter tag.

Custom converter example

A detail guide to create a JSF 2 custom converter name “URLConverter”, which is used to convert a String into an URL format (add HTTP protocol in front only :)) and store it into an Object.

1. Folder Structure

Folder structure of this example.

jsf2-custom-converter-example-folder

2. Converter class

Create a custom converter class by implementing javax.faces.convert.Converter interface.


package com.mkyong;

import javax.faces.convert.Converter;
public class URLConverter implements Converter{
	//...
}

Override following two methods :
1. getAsObject(), converts the given string value into an Object.
2. getAsString(), converts the given object into a String.


public class URLConverter implements Converter{

	@Override
	public Object getAsObject(FacesContext context, UIComponent component,
			String value) {
		
		//...
	}
	@Override
	public String getAsString(FacesContext context, UIComponent component,
			Object value) {

		//...
		
	}

Assign an converter ID with @FacesConverter annotation.


package com.mkyong;

import javax.faces.convert.Converter;
@FacesConverter("com.mkyong.URLConverter")
public class URLConverter implements Converter{
	//...
}

See full custom converter source code :

URLConverter.java


package com.mkyong;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import org.apache.commons.validator.UrlValidator;
 
@FacesConverter("com.mkyong.URLConverter")
public class URLConverter implements Converter{

	@Override
	public Object getAsObject(FacesContext context, UIComponent component,
		String value) {
		
		String HTTP = "http://";
		StringBuilder url = new StringBuilder();

		//if not start with http://, then add it
		if(!value.startsWith(HTTP, 0)){
			url.append(HTTP);
		}
		url.append(value);
		
		//use Apache common URL validator to validate URL
		UrlValidator urlValidator = new UrlValidator();
		//if URL is invalid
		if(!urlValidator.isValid(url.toString())){
			
			FacesMessage msg = 
				new FacesMessage("URL Conversion error.", 
						"Invalid URL format.");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ConverterException(msg);
		}
		
		URLBookmark urlBookmark = new URLBookmark(url.toString());
		
		return urlBookmark;
	}

	@Override
	public String getAsString(FacesContext context, UIComponent component,
			Object value) {

		return value.toString();
		
	}	
}

In this custom converter class, it’s given a converter id as “com.mkyong.URLConverter“, and converts any given String (by adding a “http” in front) into “URLBookmark” object.

In addition, if URL validation is failed, return a FacesMessage object with declared error message.

URLBookmark.java


package com.mkyong;

public class URLBookmark{
	
	String fullURL;

	public URLBookmark(String fullURL) {
		this.fullURL = fullURL;
	}

	public String getFullURL() {
		return fullURL;
	}

	public void setFullURL(String fullURL) {
		this.fullURL = fullURL;
	}
	
	public String toString(){
		return fullURL;
	}
	
}

3. Managed Bean

A normal managed bean named “user”, nothing special here.


package com.mkyong;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
@ManagedBean(name="user")
@SessionScoped
public class UserBean implements Serializable{
	
	String bookmarkURL;

	public String getBookmarkURL() {
		return bookmarkURL;
	}

	public void setBookmarkURL(String bookmarkURL) {
		this.bookmarkURL = bookmarkURL;
	}

}

4. JSF Page

Link above custom converter to JSF component via “converterId” attribute in “f:converter” tag.

default.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"
      xmlns:f="http://java.sun.com/jsf/core"
      >
    <h:body>
    	
    	<h1>Custom converter in JSF 2.0</h1>
		
	<h:form>
		
	  <h:panelGrid columns="3">
			
		Enter your bookmark URL :
				
		<h:inputText id="bookmarkURL" value="#{user.bookmarkURL}" 
			size="20" required="true" label="Bookmark URL">
			<f:converter converterId="com.mkyong.URLConverter" />
		</h:inputText>
				
		<h:message for="bookmarkURL" style="color:red" />
			
	  </h:panelGrid>
			
	  <h:commandButton value="Submit" action="result" />
			
	</h:form>	
    </h:body>
</html>

result.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"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      >
    <h:body>
    	
    	<h1>Custom converter in JSF 2.0</h1>
			
	  <h:panelGrid columns="2">
			
		Bookmark URL :  
		<h:outputText value="#{user.bookmarkURL}" />
				
	  </h:panelGrid>
			
    </h:body>
</html>

5. Demo

Enter a valid URL, without “http”.

jsf2-custom-converter-example-1

Add a “http” in front of the valid URL and display it.

jsf2-custom-converter-example-2

If an invalid URL is provided, return the declared error message.

jsf2-custom-converter-example-3

Download Source Code

Download It – JSF-2-Custom-Converter-Example.zip (11KB)

Reference

  1. J2EE doc – Create a custom converter