What to do with the inner converter of view scoped backing bean - jsf

Yet another problem among others with view scoped backing beans in JSF. I created an inner class in my view scoped backing bean. That inner class is converter. I need the inner class because I have to access some fields from my backing bean (list of select-one items in this case). Suddenly I figure out that my backing bean's #PostConstruct method is called after every request. After some inspection I realized that converter attribute is the problem and after some google search a find on (as always) BalusC's blog reason for this.
So, my question is how to make my converter to work fine, and also have my list of data which is necessary for conversion?

Decouple the converter into a stand alone class and use Application#evaluateExpressionGet() to access the view scoped bean instance inside the converter method.
ViewBean viewBean = context.getApplication().evaluateExpressionGet(context, "#{viewBean}", ViewBean.class);
This is however a bit nasty design. If I understand your concrete functional requirement of converting the selected item based on the list of available items right, an alternative is to use a generic converter which converts based on the physical <f:selectItem>/<f:selectItems> components. The JSF utility library OmniFaces has two converters for exactly this purpose, the SelectItemsConverter and SelectItemsIndexConverter.

Related

org.infinispan.commons.marshall.NotSerializableException while working with distributed Infinispan and JSF [duplicate]

There are lot of materials out there differentiating value attribute and binding attribute in JSF.
I'm interested in how both approaches differ from each other. Given:
public class User {
private String name;
private UICommand link;
// Getters and setters omitted.
}
<h:form>
<h:commandLink binding="#{user.link}" value="#{user.name}" />
</h:form>
It is pretty straight forward what happens when a value attribute is specified. The getter runs to return the name property value of the User bean. The value is printed to HTML output.
But I couldn't understand how binding works. How does the generated HTML maintain a binding with the link property of the User bean?
Below is the relevant part of the generated output after manual beautification and commenting (note that the id j_id_jsp_1847466274_1 was auto-generated and that there are two hidden input widgets).
I'm using Sun's JSF RI, version 1.2.
<form action="/TestJSF/main.jsf" enctype="application/x-www-form-urlencoded"
id="j_id_jsp_1847466274_1" method="post" name="j_id_jsp_1847466274_1">
<input name="j_id_jsp_1847466274_1" type="hidden" value="j_id_jsp_1847466274_1">
Name
<input autocomplete="off" id="javax.faces.ViewState" name="javax.faces.ViewState"
type="hidden" value="-908991273579182886:-7278326187282654551">
</form>
Where is the binding stored here?
How does it work?
When a JSF view (Facelets/JSP file) get built/restored, a JSF component tree will be produced. At that moment, the view build time, all binding attributes are evaluated (along with id attribtues and taghandlers like JSTL). When the JSF component needs to be created before being added to the component tree, JSF will check if the binding attribute returns a precreated component (i.e. non-null) and if so, then use it. If it's not precreated, then JSF will autocreate the component "the usual way" and invoke the setter behind binding attribute with the autocreated component instance as argument.
In effects, it binds a reference of the component instance in the component tree to a scoped variable. This information is in no way visible in the generated HTML representation of the component itself. This information is in no means relevant to the generated HTML output anyway. When the form is submitted and the view is restored, the JSF component tree is just rebuilt from scratch and all binding attributes will just be re-evaluated like described in above paragraph. After the component tree is recreated, JSF will restore the JSF view state into the component tree.
Component instances are request scoped!
Important to know and understand is that the concrete component instances are effectively request scoped. They're newly created on every request and their properties are filled with values from JSF view state during restore view phase. So, if you bind the component to a property of a backing bean, then the backing bean should absolutely not be in a broader scope than the request scope. See also JSF 2.0 specitication chapter 3.1.5:
3.1.5 Component Bindings
...
Component bindings are often used in conjunction with JavaBeans that are dynamically instantiated via the Managed
Bean Creation facility (see Section 5.8.1 “VariableResolver and the Default VariableResolver”). It is strongly
recommend that application developers place managed beans that are pointed at by component binding expressions in
“request” scope. This is because placing it in session or application scope would require thread-safety, since
UIComponent instances depends on running inside of a single thread. There are also potentially negative impacts on
memory management when placing a component binding in “session” scope.
Otherwise, component instances are shared among multiple requests, possibly resulting in "duplicate component ID" errors and "weird" behaviors because validators, converters and listeners declared in the view are re-attached to the existing component instance from previous request(s). The symptoms are clear: they are executed multiple times, one time more with each request within the same scope as the component is been bound to.
And, under heavy load (i.e. when multiple different HTTP requests (threads) access and manipulate the very same component instance at the same time), you may face sooner or later an application crash with e.g. Stuck thread at UIComponent.popComponentFromEL, or Threads stuck at 100% CPU utilization in HashMap during JSF saveState(), or even some "strange" IndexOutOfBoundsException or ConcurrentModificationException coming straight from JSF implementation source code while JSF is busy saving or restoring the view state (i.e. the stack trace indicates saveState() or restoreState() methods and like).
Also, as a single component basically references the rest of the entire component tree via getParent() and getChildren(), when binding a single component to a view or session scoped bean, you're essentially saving the entire JSF component tree in the HTTP session for nothing. This will get really costly in terms of available server memory when you have relatively a lot of components in the view.
Using binding on a bean property is bad practice
Regardless, using binding this way, binding a whole component instance to a bean property, even on a request scoped bean, is in JSF 2.x a rather rare use case and generally not the best practice. It indicates a design smell. You normally declare components in the view side and bind their runtime attributes like value, and perhaps others like styleClass, disabled, rendered, etc, to normal bean properties. Then, you just manipulate exactly that bean property you want instead of grabbing the whole component and calling the setter method associated with the attribute.
In cases when a component needs to be "dynamically built" based on a static model, better is to use view build time tags like JSTL, if necessary in a tag file, instead of createComponent(), new SomeComponent(), getChildren().add() and what not. See also How to refactor snippet of old JSP to some JSF equivalent?
Or, if a component needs to be "dynamically rendered" based on a dynamic model, then just use an iterator component (<ui:repeat>, <h:dataTable>, etc). See also How to dynamically add JSF components.
Composite components is a completely different story. It's completely legit to bind components inside a <cc:implementation> to the backing component (i.e. the component identified by <cc:interface componentType>. See also a.o. Split java.util.Date over two h:inputText fields representing hour and minute with f:convertDateTime and How to implement a dynamic list with a JSF 2.0 Composite Component?
Only use binding in local scope
However, sometimes you'd like to know about the state of a different component from inside a particular component, more than often in use cases related to action/value dependent validation. For that, the binding attribute can be used, but not in combination with a bean property. You can just specify an in the local EL scope unique variable name in the binding attribute like so binding="#{foo}" and the component is during render response elsewhere in the same view directly as UIComponent reference available by #{foo}. Here are several related questions where such a solution is been used in the answer:
Validate input as required only if certain command button is pressed
How to render a component only if another component is not rendered?
JSF 2 dataTable row index without dataModel
Primefaces dependent selectOneMenu and required="true"
Validate a group of fields as required when at least one of them is filled
How to change css class for the inputfield and label when validation fails?
Getting JSF-defined component with Javascript
Use an EL expression to pass a component ID to a composite component in JSF
(and that's only from the last month...)
See also:
How to use component binding in JSF right ? (request-scoped component in session scoped bean)
View scope: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
Binding attribute causes duplicate component ID found in the view
each JSF component renders itself out to HTML and has complete control over what HTML it produces. There are many tricks that can be used by JSF, and exactly which of those tricks will be used depends on the JSF implementation you are using.
Ensure that every from input has a totaly unique name, so that when the form gets submitted back to to component tree that rendered it, it is easy to tell where each component can read its value form.
The JSF component can generate javascript that submitts back to the serer, the generated javascript knows where each component is bound too, because it was generated by the component.
For things like hlink you can include binding information in the url as query params or as part of the url itself or as matrx parameters. for examples.
http:..../somelink?componentId=123 would allow jsf to look in the component tree to see that link 123 was clicked. or it could e htp:..../jsf;LinkId=123
The easiest way to answer this question is to create a JSF page with only one link, then examine the html output it produces. That way you will know exactly how this happens using the version of JSF that you are using.

Saving a Composite Component bean attribute in ViewScoped

I would like some technique/pattern advice on retaining each single bean I bind to my Composite Components.
I am adding composite components to a form pragmatically based on user actions, and when the user is finished I want to harvest the single bean behind each composite component they added. Ex: If user selects & adds 4 composite components, that's one bean for each, so when the user is finished I want the 4 beans with the user's entered values.
This seems a bit hairy in the JSF world, but I continue to dig through stackoverflow and experiment. I'm relatively new to JSF details, but having fun.
I've got the composite components loading, each being given a bean to be used as "cc.attrs.bean" and it properly adds the control to the form. Here is what I am currently doing and what I expected:
Load Composite Component
Instantiate its Bean
Save Bean reference in a separate list in a ViewScoped bean (my hook to the bean for later)
Give Bean to Composite Component (as an attribute)
Add Composite Component to form
...User interacts with form and Composite Components adding/editing values...
User finally pushes "Done" (now I need the modified beans).
Thought I could get all the user's values from the "separate list in a ViewScoped bean" from #3 above.
My preliminary experiments tell me that if I instantiate the bean, save the bean reference in a separate ViewScoped list then give the bean to the Composite Component, the bean I saved won't have the Composite Component's values. Between all the build/render phases it seems to lose the connection between the bean I saved and the bean the Composite Component is bound to.
I don't know if I should be following this path, or if I should use a FacesComponent event technique to intercept the bean attribute being passed along, or if I should be using filters, or maybe even magical pixie dust etc...
This seemed promising: I already wrap each of my user selectable Composite Components in a single common Wrapper Composite Component (lets me put a nice PrimeFaces collapsible panel frame around them). For example, I put "Composite Component A" into "Wrapper", then I add "Wrapper" to the form. If I passed the single bean as an attribute to both those Composite Components, I was hoping that the FacesComponent event "init" technique on the Wrapper could nicely capture the "real bound bean" in my separate list in the ViewScoped bean. In my attempts on this today I'm having trouble finding the right event type and getting access to the bean... and getting lots of strange errors (probably due to my lack of detailed understanding of the lifecycle).
Stack: Eclipse Mars, JSF 2.2, Mojarra 2.2, Tomcat 8.0

How to instantiate a backing bean on page load

For a project we are migrating some java applications to WebSphere 8.5. In the process we are trying to get rid of some legacy frameworks. One of them is shale (apache attic). The only component from shale that is used is the view controller to instantiate a request scoped jsf managed beans for every page. Every bean has an init method that is called on page load. I'd like to use #PostConstruct on this method. The only problem I have that the bean gets instantiated when a method on the bean is called. Unfortunately the bean is not always called and the init method does populate data on a session scoped bean. There is a naming convention that links pages and beans so we could use a listener to instantiate the bean based on the request. Another solution might be changing the scope to viewscope (probably to much a hassle on websphere 8.5).
I was wondering if there is something I can do to make the PostConstruct work? And are there other options I'm missing?
edit:
I have a PhaseListener in place that performs the basic functionality. It matches the requested page to the corresponding bean (by naming convention). The following is used to instantiate the bean but it looks a bit ugly.
expressionFactory.createValueExpression(elContext, "#{" + managedBeanName + "}", Object.class)
Is there a more elegant way to do this?
Perhaps you could try using <f:event/> ?
In your view, you could add this to the page.
<f:event type="postAddToView" listener="#{backingBean.myInitMethod()"/>
https://stackoverflow.com/a/14004230/4706826
Gives you info on when the events get executed.
Put a #PostConstruct annotated method in the backing bean. This annotation tells the bean to execute the annotated method every time its constructor is being called.
Example:
#ManagedBean
#ViewScoped
public class MyManagedBean{
#PostConstruct
public void initView() throws Exception{
...initialize page values, execute database queries, etc.
}

JSF Managed bean and managed property both necessary?

I'm new to JSF and was wondering:
If I have a controller that handles all the work for a given page and a bean that holds all the data for said page, is It necessary to have both the
#ManagedProperty(value="#{myBean}")
annotation on the controller and the
#ManagedBean(name="myBean")
#SessionScoped
annotations on the form bean?
Managed beans in JSF are used to store the state of a web page. The JSF implementation is responsible for creating and discarding the bean objects( hence the name managed bean).
For every class you write #ManagedBean, the bean object is created by the JSF implementation as and when it detects an usage of the bean with the name(you can either sepcify a bean name or leave it to JSF to use the default name-class name with the first character changed to lowercase). The object created is placed in a map of the specified scope. Each scope has a map that it uses to store bean objects which have that scope specified.
Now if you need the values of these beans in your controller, you have to inject it using the ManagedProperty annotation. Note that you would need to provide the controller with a setter method for the managedProperty.
So to answer your question, the managedBean annotation is required to tell the JSF implementation to manage the bean instance and store the values in the table specific to the session scope. And the ManagedProperty annotation is needed to use that bean stored in the current session so that you can access all of its values.
We use #ManagedBean annotation to register a java bean with a JSF framework. This is a replacement for a faces-config.xml <managed-bean> element. We typically do not use name attribute because it already defaults to a simple class name camel cased.
We use #RequestScope and other scope annotations to explicitly specify the scope we want via annotation. This is equivalent to specifying<managed-bean-scope> xml entry. If you don't specify the scope it will be defaulted to #NoneScoped.
We use #ManagedProperty and specify an EL-expression in its value attribute to use JSF-provided dependency injection engine for JSF artifacts like other managed beans with broader scopes and EL-defined variables like param. We do it in case we need the injected values in other JSF artifacts, most typically beans. The injected values are available in bean's #PostConstruct-annotated method. This is an alternative to <managed-property> xml entry.
To sum it up. Use #ManagedBean #RequestScoped to register a bean with JSF framework. Use #ManagedProperty inside this bean to be able to reference among others other JSF beans with the same or broader scopes in this bean. In case you don't need to reference other beans in the created bean you don't need to use the #ManagedProperty annotation as it's purely optional.

bean and jsf validation annotation inisde managed bean vs entity bean

I'm new in JSF and not sure about a few fundamental issues.
I found i few ways for defining validation for my input fields, but i'm not sure which is the right way to do it.
I'm using bean validation and jsf validation by using ExtVal.
should I use the validation annotation like #Size , #Length inside my entity bean, or should it be inside the managed bean? what is the diffrence for each option?
This question leads me to a more basic one , that I still don't really understand -
I have an entity bean with fields and their setters and getters, also I have a managed bean and a xhtml file with a form that displays the fileds inside inputs.
should I define the same fields with their getters and setters inside the managed bean? and when approaching them from the xhtml file I do it by MBname.FiledName ? or is it better not to create the fields again in the managed bean and approch them from the xhtml by calling MBname.details.FiledName (when details return the object) ?
again what is the diffrence for each approch?
Thank's In Advance.
should I use the validation annotation like #Size , #Length inside my entity bean, or should it be inside the managed bean? what is the diffrence for each option?
Depends on the concrete functional requirement. Key point is: how reuseable should the validation be? If configured at entity level, it's reuseable for all frameworks other than JSF. If configured at JSF level, it's not reuseable for frameworks other than JSF which happen to use the same entity.
should I define the same fields with their getters and setters inside the managed bean? and when approaching them from the xhtml file I do it by MBname.FiledName ? or is it better not to create the fields again in the managed bean and approch them from the xhtml by calling MBname.details.FiledName (when details return the object) ? again what is the diffrence for each approch?
You should not duplicate/expand the data model in the controller. This makes no sense. This is not DRY and is thus only maintenance headache.

Resources