Post details: JSF and Java 5.0 Enums

Sep 30, 2005 : JSF and Java 5.0 Enums

Rich Hightower explains how he set up JSF to use Java Enums but his code can be greatly simplified.

First, instead of manually mapping keys to enum constants, you could add a key parameter to each constant which gets passed to the constructor. See Sun's Enum guide for more info. And then you could loop through MyEnumClass.values() to find what you need for the reverse mapping.

But you don't need to specify keys at all. Using .toString() and Enum.valueOf() work just fine as a key in JSF. (You'll see them used later in the converter.) Besides, putting keys in your Enum just so JSF can use them is mixing presentation and logic. Your Enum class doesn't need anything special to work with JSF.

The backing bean still needs to provide a list of choices for each select box. But we can do it with a generic method.

/** provide all choices from the ColorType enum */
public Map getColorTypeChoices() {
	Map<String,ColorType> choices = new HashMap<String,ColorType>();
	for (ColorType type : ColorType.values()) {
		choices.put(type.getLabel(), type);
	}
	return choices;
}

And the converter can be improved to a single one-size-fits-all Enum converter.

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

public class EnumTypeConverter implements Converter {

	public Object getAsObject(FacesContext context, UIComponent comp,
			String value) throws ConverterException {
		Class enumType = comp.getValueBinding("value").getType(context);
		return Enum.valueOf(enumType, value);
	}

	public String getAsString(FacesContext context, UIComponent component,
			Object object) throws ConverterException {
		if (object == null) {
			return null;
		}
		Enum type = (Enum) object;
		return type.toString();
	}

}

For each enum class, use this as the <converter-class> in faces-config.xml

The JSF tags are straightforward:

<h:selectOneListbox id="colorType" required="true" value="#{formbean.form.colorType}">
	<f:selectItems value="#{formbean.colorTypeChoices}" />
</h:selectOneListbox>

Based on all the improvements made here, I'm pretty sure they could be further simplified by creating a selectItemsFromEnum facet. More on that later, hopefully.

Comments, Pingbacks:

Comment from: Dave Brondsema [Member] · http://brondsema.net/
Thanks, Dave - I was puzzling over that myself.
Dad
Permalink 10/06/05 @ 08:42
Comment from: Arwr [Visitor]
This site looks horrid in firefox (bad scrolling). May want to choose a better blogger software
Permalink 10/08/05 @ 17:38
Comment from: Dave Brondsema [Member] · http://brondsema.net/
Arwr, I haven't had time to customize a skin yet. But you're right, I do need to.
Permalink 10/08/05 @ 17:49
Comment from: AJP [Visitor] · http://ajp.net
Ooooh. Pretty and Pink. Me Likey!*

* Means, that although fine, pink doesn't seem "you". Css Reboot is Nov. 1st. Ready set go.
Permalink 10/12/05 @ 10:14
Comment from: Horia [Visitor]
That's great! Nice solution to retrieve the Enum type through reflection on the component's value accessed as parameter!
Permalink 07/21/06 @ 12:22
Comment from: Mario Ivanovits [Visitor]
Hi!

I think its better to use "name()" as "toString()" as toString might be customized by the developer.

public enum MyEnum
{
ABC("myAbc"),
DEF("myDef"),
UIO("myAbc");

private final String description;
MyEnum(String description)
{
this.description = description;
}
public String toString()
{
return this.description;
}
}

I even used ordinal() in MyFaces.
http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox15/core/src/main/java/org/apache/myfaces/custom/dynaForm/jsfext/EnumConverter.java?view=markup

As you can see, I render a special string with "class@ordinal" that way I avoid the use of valueBinding.getType() thing which can fail if it e.g. points to a list or method without a simple Object as return type (Though, not very likely I admit ;-) )
For sure, that way the user isn't really able to input the value of an enum, though, I think the main use case of an enum in JSF is to show the user a selection menu.

Just additional ideas ...
Permalink 10/18/06 @ 03:52
Comment from: Lluis Turro [Visitor] · http://www.xmlportal.net
Mario got the point. Mapping enums in JSF has another issue: internationalization.

Using name you can also map to i18n resources.
Permalink 07/25/07 @ 05:07
Comment from: Nikos [Visitor]
Interesting post, thank you.

A detail: You dont need to set a converter for each enum type; just use java.lang.Enum in the converter-for-class element of faces-config.xml.

Worked for Faces 1.2 RI from Sun.
Permalink 08/30/07 @ 05:53
Comment from: Joao Clarisso [Visitor]
Great post. Very useful and explanatory.

But an annoying problem with Enums and JSF is when you try to use them in selectItens



Permalink 09/28/07 @ 13:12
Comment from: Atif Faridi [Visitor]
Mario -

I like the idea of using the final superclass methods name() or ordinal() over a mutable toString(). However, displaying the fully qualified class name to the world is a bit troubling. Is there a fast and lightweight symmetric encryption/hashing/obfuscation algorithm that can be employed to prevent browsers from displaying this?
Permalink 05/23/08 @ 10:54
Comment from: Don Andrews [Visitor]
I'd like the label list sorted. The Apache Commons TreeMap is not parameterized, so would I have to create my own?
Permalink 08/01/08 @ 18:48
Comment from: Don Andrews [Visitor]
My ad, my IDE imported some other TreeMap, java.util.TreeMap works fine.
Permalink 08/01/08 @ 18:52
Comment from: Andrew [Visitor]
Thanks! Was looking for a solution for a generic enum type converter and this did the job great.
Permalink 09/17/08 @ 06:47
Comment from: Roger Keays [Visitor] · http:://www.ilikespam.com
Here's a simpler method which uses getters and setters to marshal enums to strings:

http://www.ilikespam.com/blog/using-enums-in-el
Permalink 04/11/11 @ 00:08

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.
What is the 2-letter abbreviation for Michigan?
Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
Options:
 
(Line breaks become <br />)
(Set cookies for name, email & url)

<  August 2019  >
Mon Tue Wed Thu Fri Sat Sun
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Categories


Archives

Misc

Syndicate this blog XML

powered by
b2evolution