When to use parameterized method invocations introduced with EL 2.2 (especially in JSF 2.x )? - jsf

In the past I used a lot of getter and setter methods to move as much boolean logic as possible from facelet files to JSF backing beans.
This way, the interface of a view was given by the getter and setter methods of its backing bean as well as by the action methods of the backing bean.
An advantage of this approach is that the facelet files are rather logic-free and ,therefore, all logic is within the backing beans and can be unit tested.
But with EL 2.2 another programming style became possible. In EL 2.2 you can invoke methods with expressions like
#{bean.collection.size()},
#{bean.collection.add(elem)},
#{bean.property.substring(0, bean.property.indexOf(something))}.
Is the usage of rather complex expressions like parameterized method invocations good style now or do you rather advise against using such expressions?
Is there a rule of thumb when to use the new method invocation expressions and when not?

The major guideline is the following: reduce as much 'model' logic from the view as possible and leave only the 'view' logic. EL 2.2 made possible some model simplification and reduced the need for creation of artificial properies of JSF beans. Invocation of methods with parameters also enables to pass the necessary information from the view to the controller which would be tedious without that opportunity.
You can call arbitrary methods to access the model from the view that the view part relies on, but you should never call methods that modifies the model from the view.
Let me elaborate on that.
Some legal examples:
evaluate non-accessor methods when building view:
render UI components based on some conditions like rendered="#{request.isUserInRole('administrator')}";
make collection modifications where necessary like <ui:repeat value="#{bean.set.toArray()}" ... >
conditionally evaluate UI component / HTML element attributes like class="#{bean.name.contains('special') ? 'special' : ''}";
output non-accessor data like there are #{bean.list.size()} elements.
pass information to the controller in action methods or listeners:
execute action methods with currently iterated variables like var="data" and action="#{bean.action(data)}" with public String action(Data data);
pass additional data, like current iteration index, in listeners like varStatus="status" and actionListener="#{bean.action(status.index)}" with public String action(int index).
Some to-be-avoided examples:
use EL operators when possible:
use #{not empty bean.list} instead of #{bean.list.size() gt 0}.
use method call with parameters instead of extending the model:
use #{bean.name.contains('special')} instead of #{bean.special} with public boolean isSpecial() {return name.contains("special");}.
prefer leaving view logic in view for plain rendering of the right things and create model logic in case it applies purely to the model:
in case you need to perform some calculations to change the appearance of an object, do that in view directly without changing the model, in case some property is inherent to the model itself, introduce it directly in the model and refer to it from the view.
Some illegal examples:
modify the model from the view:
do not use EL 2.2 possibility of calling methods with parameters to break the MVC paradigm, i.e. do not call #{bean.list.add(element)} from the view side.
Of course, all things said apply to the cases that your goals don't contain targeting at the older servers without EL 2.2 support.
As a bigger picture, I'd recommend to also see BalusC's explanation of what MVC architecture represents within the context of JSF.

Personally, i prefer using "complex" EL expressions when really needed, and take any bit logic/traitement to the correspondant managed-beans.
For example: the first example you put is the only one that i may sometimes use directly, the two others however should be for me put in action methods with void/String returning type according to the need.

Use El 2.2 to reduce our JSF code, e.g. setPropertyActionListener is made redundant, see
JSF Core Tag :setPropertyActionListener vs attribute vs param

Related

How exactly does p:panelGrid extends h:panelGrid

I'm using Primefaces and I know that p:panelGrid extends h:panelGrid as it's clearly stated in the documentation.
However I can't see the exact difference between them. What extra functionalities does p:panelGrid provide? In which cases should I prefer using the Primefaces version over the HTML Basic one?
Although p:panelGrid extends h:panelGrid, it actually lacks many of the attributes that h:panelGrid contains. Which ultimately got me confused.
I can't speak for PrimeFaces' actual intention (I'm no PrimeFaces developer), but based on my observations so far, I can only conclude that they omitted attributes which only invite bad practices in HTML perspective (mainly HTML-deprecated attributes — use CSS instead) or makes no sense otherwise (and are better at its place in a parent or child component). I can only say that it's a Good Thing.
Upon further inspection in the source code I can also confirm that it doesn't technically extend from <h:panelGrid> (HtmlPanelGrid class), but from the UIPanel superclass (which is also used by a.o. <h:panelGroup>). This design decision is most likely done to have more flexibility in the rendered output as shown in the showcase.
Generally, you should only prefer an enhanced component whenever you start to actually need the enhanced/new feature. This usually only happens once you figure out you actually need such one feature and discover that it is missing in the standard component. You'd then usually already know the keywords you're looking for and simply start exploring the component libraries using those keywords if they haven't already implemented it.

Can JSF be configured to not invoke Entity setter unless the field actually changed?

When a JSF form field is wired into an entity bean field (which is mapped to a DB field), each setter in the entity bean is called regardless of whether the user changed the form field value in the front end, i.e. the setters on unchanged fields are invoked the same as those that have changed but their new value is the same as the old value.
My question is simple: Is there a way to configure JSF to only call the setters mapped to the fields that have changed in the front end? The reason for this is that I have a requirement by which I have to detect deltas on every persist and log them, more about which can be read in this question.
Maybe I didn't understand you clearly, but why are you mapping directly your entity beans to a JSF view ?! IMHO it would be better if you add managed beans between your JSF pages and the entities in order to better separate your business logic from data access.
Any way, I think the easiest solution to impelement for that case is by making use of Value Change Events which are invoked "normally" after the Process Validations phase (unless you make use of the immediate attribute).
The good news about Value Change Events (regarding your example) is they are invoked ONLY after you force form submit using JavaScript or Command components AND the new value is different from the old value.
So, as an example on how to use value change listeners, you can add valueChangeListner attribute to each of your JSF tags like following:
<h:inputText id="input" value="#{someBean.someValue}"
valueChangeListener="#{someBean.valueChanged} />
Then, implement your valueChanged() method to look something like:
public void valueChanged(ValueChangeEvent event) {
// You can use event.getOldValue() and event.getNewValue() to get the old or the new value
}
Using the above implementation, may help you to separate your logging code (it will be included in the listeners) from your managed properties setters.
NB: Value Change Listeners may also be implemetend otherwise using the f:valueChangeListener Tag, but this is not the best choice for your example (you can find some examples in the section below, just in case)
See also:
Valuechangelistener Doubt in JSF
JSF 2 valueChangeListener example
When to use valueChangeListener or f:ajax listener?

How to get UIComponent value in Java?

I have a method in my JSF controller that is invoked by an ajax tag nested inside a visual component (really irrelevant which one). The method takes a single argument of type AjaxBehaviorEvent, from which I can obtain a Java representation of the invoking HTML visual component as a UIComponent and also downcast it to its specific corresponding type (e.g. h:inputText corresponding to HtmlInputText).
I understand that, in most cases, the value of the HTML visual component would be retrieved easily by referencing either the controller or entity [g|s]etters to which the form fields are mapped in the view. However, in my particular case, I would like to fetch the value of the visual component (in my case a form field) through its Java object rendering. While studying the faces API, I found ways to read various properties of the object, such as the ID or context but not the value that the component currently holds in the view.
Can anybody explain whether I am just not finding the right way to read it or it is so by design? If the latter, can you explain why it is designed like that? Is it to disable "backdoor" access to form fields as opposed to going through the view mapping?
There are a multitude of ways to pull values off a component. Going by what you already have UIInputt#getValue() and UIInput#getSubmittedValue() will provide the value.
The UIInput#getSubmittedValue() is fit for the purpose only between the APPLY_REQUEST_VALUES and VALIDATE phases of the JSF request. All other phases after, use the UIInputt#getValue(). You'll be using UIInput instead of the raw UIComponent you pulled from the event (UIInput extends UIComponent and it's the parent class for all input components that accept user-edited values). What you'll have will eventually look like:
UIInput theInput = (UIInput)event.getSource();
Object theValue = theInput.getValue();
There are other ways (not as clean) to get values within the request lifecycle also

component binding vs findComponent() - when to use which?

As described in this question I try to perform some field validation in a form on the backing bean side. For this I would like to access the violating fields to mark them.
From searching the web there seem to be two ways to do this:
store the components in the backing bean for access and use them in the JSF pages via the binding attribute.
Use standard value binding in the JSF pages and when needing access to a component from the bean, look it up via UIViewRoot.findComponent(String id)
As far as I can see both ways have drawbacks:
Component bindings blows up the backing bean with variables and getters/setters, some sites strongly discourage the use of component binding at all. In any case, a request scope is advised. On the other hand, findComponent() always traverses the tree, which may or may not be costly, right? (Plus, at the moment I can't find my component at all, but that is another problem)
Which would be the way to go? Are these interchangeable alternatives and if not, based on what criteria do you chose? Currently I just don't have enough insight to make a decent decision...
First of all, regardless of the choice, both are a poor practice. See also How does the 'binding' attribute work in JSF? When and how should it be used?
If you had to make the choice, component bindings are definitely faster and cheaper. It makes logically completely sense that a tree scan as done by UIComponent#findComponent() has its performance implications.
Indeed, the backing bean holding the component bindings must be request scoped, but you could easily inject a different scoped backing bean holding the business logic in it by #ManagedProperty.
A cleaner approach would be to use a Map as holder of all component bindings. You only need to add the following entry to faces-config.xml:
<managed-bean>
<managed-bean-name>components</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
This can just be used as
<h:inputSome binding="#{components.input1}" />
<h:inputSome binding="#{components.input2}" />
<h:inputSome binding="#{components.input3}" />
And this can be obtained in other beans as
Map<String, UIComponent> components = (Map<String, UIComponent>) externalContext.getRequestMap().get("components");
This way you don't need to worry about specifying individual properties/getters/setters. In the above example, the Map will contain three entries with keys input1, input2 and input3, each with the respective UIComponent instance as value.
Unrelated to the concrete question, there may be a much simpler solution to the concrete problem as you described in the other question than performing the validation in the action method (which is actually Bad Design). I've posted an answer over there.

Separation of concerns in JSF Beans?

Im currently using JSF2, and i notice the JSF bean could have a lot of responsibility, and if combined will look like lots of codes. These include :
holding the state / data
could be a backing bean for the UI component
action methods definition
action listener methods definition
navigation
calling the services
all the setter n getters
Does it make anysense to break these into several classes or do you usually combine all of them together ?
Currenly for every JSF Bean, i define another class to hold the view data / state along with the setter getters.
How do you usually do it ? Please share your experience !
Thank you =)
Every property which is been used in action(listener) methods needs to stay in the backing bean. The remnant most likely belongs in its own class which can in turn be a different (managed/entity)bean, eventually as a (managed)property of the bean where it originated.

Resources