bean and jsf validation annotation inisde managed bean vs entity bean - jsf

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.

Related

How ManagedBeans figure out to which facelet or xhtml file they belong?

In JSF, I wonder how a ManagedBean understands that it should be available to an xhtml or facelet ?
To bind component values and objects to managed bean properties or to reference managed bean methods from component tags, page authors should use the Expression Language syntax.
When user make request to the page that contains EL, that refers to specific manage bean, this bean will be instantiated by JSF framework (except managed beans that have attribute eager="true", that means that managed bean is created before it is requested for the first time).
So the fact is that managed bean will be instantiated by JSF container and works as a model for the appropriate UI Component so the Facelet will know about the Bean, not vice versa

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.

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

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.

Resources