JSF Showcase

f:converter

The f:converter Facelet tag exposes the functionality of a Converter inside Facelet views. f:converter tags facilitate conversion of complex data structures into UI data and back.

General Usage

Converters must be annotated with @FacesConverter (or declared as a converter in a faces-config.xml file) and implement Converter in order to be accessible via the f:converter tag.

Selected Country Id:1, Selected Country Name:China

Source Code

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core"
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html">

	<h:form>
		<h:selectOneMenu id="selectOneMenuId" value="#{converterModelBean.country}">
			<f:selectItems value="#{countryService.allCountries}" var="country" itemValue="#{country}"
				itemLabel="#{country.countryName}" />
			<f:converter converterId="com.liferay.faces.showcase.converter.CountryConverter" />
		</h:selectOneMenu>
		<hr />
		<h:commandButton value="#{i18n['submit']}">
			 <f:ajax render="@form" execute="@form"/>
		</h:commandButton>
		<h:outputText value="#{i18n['selected-country-id']}:#{converterModelBean.country.countryId}, #{i18n['selected-country-name']}:#{converterModelBean.country.countryName}" />
	</h:form>

</ui:composition>
@ManagedBean
@RequestScoped
public class ConverterModelBean {

	@ManagedProperty(value = "#{countryService}")
	private CountryService countryService;

	// Private properties
	private Country country;
	private double number = 3.141516;

	public Country getCountry() {
		return country;
	}

	public CountryService getCountryService() {
		return countryService;
	}

	public double getNumber() {
		return number;
	}

	@PostConstruct
	public void postConstruct() {
		this.country = countryService.getAllCountries().get(0);
	}

	public void setCountry(Country country) {
		this.country = country;
	}

	public void setCountryService(CountryService countryService) {
		this.countryService = countryService;
	}

	public void setNumber(double number) {
		this.number = number;
	}

}
@FacesConverter(value = "com.liferay.faces.showcase.converter.CountryConverter")
public class CountryConverter implements Converter {

	// Static field must be declared volatile in order for the double-check idiom to work (requires JRE 1.5+)
	private static volatile Map<Long, Country> countryMap;

	@Override
	public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
		Object countryObject = null;

		if ((value != null) && !"".equals(value)) {
			Long countryId = Long.parseLong(value);

			countryObject = getCountryMap(facesContext).get(countryId);
		}

		return countryObject;
	}

	@Override
	public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
		String strValue = "";

		if (value != null) {
			Country country = (Country) value;
			strValue = Long.toString(country.getCountryId());
		}

		return strValue;
	}

	protected Map<Long, Country> getCountryMap(FacesContext facesContext) {

		Map<Long, Country> countryMap = CountryConverter.countryMap;

		// First check without locking (not yet thread-safe)
		if (countryMap == null) {

			synchronized (CountryConverter.class) {

				countryMap = CountryConverter.countryMap;

				// Second check with locking (thread-safe)
				if (countryMap == null) {

					ELResolver elResolver = facesContext.getApplication().getELResolver();
					ELContext elContext = facesContext.getELContext();
					CountryService countryService = (CountryService) elResolver.getValue(elContext, null,
							"countryService");
					countryMap = CountryConverter.countryMap = countryService.getCountryMap();
				}
			}
		}

		return countryMap;
	}
}
Liferay Faces Bridge Implementation 4.1.0 + Showcase Common 3.0.1 + Liferay Faces Util 3.1.0 + Mojarra 2.2.14