Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF, EL, Managed Beans - How to tell what the getter & setter signatures are?

Tags:

javabeans

jsf

el

With JSF, Managed Beans, & EL 2.2 I know generally that an expression of the form:

#{bean.value}

Will map to a corresponding set of functions in a managed bean class like so:

@ManagedBean
class Bean {
    private String value;
    public String getValue() { return value; }
    public void setValue( String s ) { value = s; }
}

It is also possible to get and set properties of a map:

#{bean.value['key']}

Backed by something like:

@ManagedBean
class Bean {
    private Map<String, Boolean> kvMap;
    public boolean getValue( String key ) { return kvMap.get( key ); }
    public void setValue( String key, boolean value ) { kvMap.put( key, value ); }
}

So far so good.

I'm finding as I spend more time with JSF however that I'm trying to write reusable chunks of code. Specifically, small blocks of xhtml in <ui:composition> blocks that I can include via <ui:include>. What's more, many of the more useful things for me are things like nested sets of checkboxes (our UI designer is just gaga over them ;-), and there <ui:repeat> becomes very handy.

Invariably, in order to use <ui:repeat> and <ui:include> without an ungodly amount of typing, I've been using aliases, either created via <ui:param> or inline with something like the var attribute of <ui:repeat>.

As I've been writing more and more nested UIComponents, particularly things that get their values from maps within maps, I'm finding it harder and harder to deduce the correct setter method signature that JSF will look for when submitting a form (for some reason writing getters seems to be more natural).

My question for you gurus then is:

Is there some way to get JSF to tell me what it expects a setter signature to look like? Since JSF generally doesn't complain about an expression that resolves to a getter-only (thinking it is a read-only property), I find the lack of feedback frustrating and it seems to require a lot of fiddling with different method signatures before I finally hit that magic right one.

I'm hoping there's some technique, say a FacesContext... query at runtime or looking in some compiled intermediate like a class file that would point me to the correct setter signature for a deeply nested property. If there is such a thing I think it would save me a lot of time trying to figure out how to get a setter constructed by trial and error.

Hopefully I've articulated clearly enough what I'm after, thanks in advance for your replies.

like image 729
par Avatar asked May 15 '12 06:05

par


People also ask

What does JSF use to locate the beans that are managed within the JSF application?

The @RequestScoped annotation is used to provide scope for ManagedBean. You can use annotations to define the scope in which the bean will be stored.

What scopes are available for a managed bean?

You can specify one of the following scopes for a bean class: Application (@ApplicationScoped): Application scope persists across all users' interactions with a web application. Session (@SessionScoped): Session scope persists across multiple HTTP requests in a web application.

How does Managed Bean work?

Managed Bean is a regular Java Bean class registered with JSF. In other words, Managed Beans is a Java bean managed by JSF framework. Managed bean contains the getter and setter methods, business logic, or even a backing bean (a bean contains all the HTML form value). Managed beans works as Model for UI component.

What is the difference between managed bean and backing bean?

1) BB: A backing bean is any bean that is referenced by a form. MB: A managed bean is a backing bean that has been registered with JSF (in faces-config. xml) and it automatically created (and optionally initialized) by JSF when it is needed.


1 Answers

I understand that your question basically boils down to "How should a setter for a Map look like?".

The answer is simple: you don't need any one. EL uses the put() method on the Map itself. You only need to provide a getter for the whole Map. On getting map values, EL will use the get() method of the Map itself. This is all behind the scenes done by the builtin MapELResolver.

So this should do:

@ManagedBean
class Bean {
    private Map<String, Boolean> kvMap;
    public Map<String, Boolean> getValue() { return kvMap; }
}

which is to be used as #{bean.value['key']} or #{bean.value.key} if the key doesn't contain periods. You can just use it in input components as well.

<h:selectBooleanCheckbox value="#{bean.value.key}" />

As to the tooling, well, the JBoss Tools plugin for Eclipse has good EL autocomplete support for normal javabeans, but it can't autocomplete map keys. Further Eclipse has its own facilities to autogenerate bean properties along with getters and setters based on a list or existing properties.

like image 159
BalusC Avatar answered Oct 17 '22 11:10

BalusC