How can i send a parameter to be used in the #PostConstruct method of a backing bean? - jsf

I need to preload some data to be displayed when the page loads. The initialization steps are performed on a #PostConstruct-annotated method but now i need to use a parameter in order to get the data.
What i'm trying to do:
#PostConstruct
public void init()
{
List data = getDataFromDB(parameter) /*Need to read a parameter created somewhere else*/
}
Is there a way to achieve this?
Thanks in advance

It's kind of hard to say what you mean by "a parameter set somewhere else". I will assume that "somewhere else" means "sent from browser by HTTP". In such case you should create a standard property in your managed bean and:
in JSF 2.0 you could annotate it with #ManagedProperty("#{param.nameOfParameterToRead}")
in JSF 1.2 and less - use managed-property element in your bean description (faces-config.xml).
Like this:
#ManagedBean
#RequestScoped
class MyManagedBean {
#ManagedProperty("#{param.id}")
public Integer id;
#PostConstruct
public void init(){
data = getDataFromDB(id)
}
// setters and getters (mandatory, even though annotation is on an attribute!!!)
}
Careful: injecting properties does not use JSF converters, so it is best to inject strings and take care of conversion in your own code.

how about reading from Properties file, or fetching List from DB ??

Related

How to have one instance of Backing Bean per Browser tab?

My environment: Java 7/JSF 2.1/PrimeFaces 6.1.
My goal: to have a certain page of my application instantiated many times, one for each browser tab, each one with a different context.
My problem: everytime I open a second browser tab requesting from the same url, but with different object id, the previous one is destroyed, so only one backing bean instance is kept alive.
How do I know that: In my backing bean I have one method annotated with #PosConstruct and other with #PreDestroy, so I can track the life cicle of the instances.
My backing bean is annotated as follows:
#ViewController
public class MyBackingBeanMB extends AbstractBackingBeanMB {
private static final long serialVersionUID = 1L;
// many fields and methods
}
The #ViewController annotation is provided by the application framework I have to use. Such an annotation is declared as:
#Named
#Controller
#Stereotype
#ViewScoped // For me, this should do the trick, but...
#Target(value={TYPE})
#Retention(value=RUNTIME)
#Inherited
public #interface ViewController {
}
Update 1:
The #Controller annotation is also provided by the framework I use and is declared as:
#InterceptorBinding
#Inherited
#Target({ TYPE, METHOD })
#Retention(RUNTIME)
public #interface Controller {
}
Any ideas of what could be wrong?
TIA.
After some digging in the Internet I found Apache DeltaSpike, which provider a new kind of managed bean scope, WindowScoped.
Managed beans annotated with #WindowScoped` operate just like I wanted, providing me with the exact behaviour I needed and it is absolutely compatible with the framework I have to use.

jsf 2 best one managed bean multiple views

I`m kind of noob to JSF and I'm trying to figure out which would be the most elegant solution for the following scenario:
Let's say that I have a user managed bean called UserMB:
#ManagedBean
public class UserMB {
private User user;
private List<User> users;
// getters and setters here
public void addUser(User user){
// do add user logic here
}
public List<User> listAllUsers(){
// do list All users logic here
}
#PostConstruct
private void init(){
// populate List<user> users - for the listAllUsers scenario
}
}
Let`s assume that i do not have a form to submit directly to listAllUsers() method, but instead i want to see all users when I open the page list-all-users.xhtml.
When I hit the managed bean from addUser.xhtml a query will be performed to DB to load all users because the bean will not know if i want to use listAllUsers() method or addUser() method.
Should i split this functionality in 2 managed beans ?
Because if so I would have to create several managed beans to deal with "User" business (ie. in Struts2 i would have only one Action that would take care of all user interactions).
P.S. I know that there is the solution to populate List in getter method but I read one article of BalusC that advise us not to do this...
Should i split this functionality in 2 managed beans ?
Yes. Use one bean per view/form. Keep the backing bean class as slick as possible. Don't give it too much responsibilities.

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

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.
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.

Refresh managed session bean in JSF 2.0

After I commit some data into the database I want my session beans to automatically refresh themselves to reflect the recently committed data. How do I achieve this when using managed session beans in JSF 2.0?
Currently I have to restart the web server in order for the sessions to clear and load anew again.
2 ways:
Put them in the view scope instead. Storing view-specific data sessionwide is a waste. If you have a performance concern, you should concentrate on implementing connection pooling, DB-level pagination and/or caching in the persistence layer (JPA2 for example supports second level caching).
#ManagedBean
#ViewScoped
public class FooBean {
// ...
}
Add a public load() method so that it can be invoked from the action method (if necessary, from another bean).
#ManagedBean
#SessionScoped
public class FooBean {
private List<Foo> foos;
#EJB
private FooService fooService;
#PostConstruct
public void load() {
foos = fooService.list();
}
// ...
}
which can be invoked in action method inside the same bean (if you submit the form to the very same managed bean of course):
public void submit() {
fooService.save(foos);
load();
}
or from an action method in another bean (for the case that your managed bean design is a bit off from usual):
#ManagedProperty("#{fooBean}")
private FooBean fooBean;
public void submit() {
fooService.save(foos);
fooBean.load();
}
This of course only affects the current session. If you'd like to affect other sessions as well, you should really consider putting them in the view scope instead, as suggested in the 1st way.
See also:
How to choose the right bean scope?

#postConstruct in JSF 1.1

How do I simulate the #postConstruct behaviour in JSF 1.1 like as in JSF 1.2 and newer?
Actually, I want to call a bean method automatically during page loading?
I am using IceFaces 1.8 on JSF 1.1.
The point of #PostConstruct is to provide a hook to execute some code after all managed properties (as in <managed-property> or #ManagedProperty) are been set and all dependency injections (e.g. #EJB, #Resource, #Inject and so on) have taken place.
If you don't have any of them, just use the bean's constructor.
public class Bean {
public Bean() {
// Just do your job here. Don't do it the hard way.
}
// ...
}
Or if you actually want to execute it when a specific property has been set, then do the job in the setter while null-checking the current property value.
public class Bean {
private SomeObject someManagedProperty;
public void setSomeManagedProperty(someManagedProperty) {
if (this.someManagedProperty == null && someManagedProperty != null) {
// First-time set, now you can do your job here.
}
this.someManagedProperty = someManagedProperty;
}
// ...
}
Update as per the comments:
I meant to execute the method every time the page is loaded
The #PostConstruct doesn't do that. However, if the bean is request scoped, then you will see the same effect. You seem to be using a session or application scoped managed bean to manage request scoped data. This is in essence wrong. You should convert it to a request scoped bean. Any real session scoped data can be split into a session scoped bean which you then inject by <managed-property>.

Resources