I want to get the value with the getter method, but it doesn't work. I use SessionScoped into my two managed-beans.
<h:outputLabel for="commentInput" value="Comment:" />
<p:inputTextarea id="commentInput" value="#{dashboardBean.currentComment}" rows="6" cols="25" label="commentInput" required="true"/>
#ManagedBean
#SessionScoped
public class DashboardBean implements Serializable
{
private String _currentComment = null;
public String getCurrentComment() {
return this._currentComment;
}
public void setCurrentComment(String _currentComment) {
this._currentComment = _currentComment;
}
}
If i call getter in this class, it's works.
But in the other class:
#ManagedBean
#SessionScoped
public class PanelListener extends AjaxBehaviorListenerImpl
{
private DashboardBean _dashDashboardBean = null;
public void editMemo(ActionEvent actionEvent)
{
System.out.println("Statements ==== [ " + _dashDashboardBean.getCurrentComment() + " ]");
}
}
I have an NullPointerException.
You need to use #ManagedProperty annotation to inject one bean into another.
#ManagedProperty("#{dashboardBean}")
private DashboardBean bean;
public DashboardBean getBean(){
return this.bean;
}
public void setBean(DashboardBean bean){
this.bean = bean;
}
Make sure the scope of the ManagedProperty is greater than or equal to the scope of bean in which you are injecting.
so here, DashBoardBean should have scope greater than or equal to PanelListener
Please note that JSF needs public getters and setters to access the fields
You have to use #ManagedProperty annotation. So try this in PanelListener, note that you need a setter to perform the bean injection. You can also only inject beana with greater or same scope to the bean with lower scopes (so for example you can inject SessionScoped to the RequestScoped but not the other way around).
#ManagedProperty("#{dashboardBean}")
private DashboardBean bean;
private void setDashboardBean(DashboardBean bean) {
this.bean = bean;
}
Related
I read the other posts about this subject but I still can't get it to work
This are my beans:
Bean1:
#ManagedBean()
#SessionScoped
public class Bean1 implements Serializable {
//Here are some important Properties
public String buttonPressed() {
return "bean2.xhtml";
}
}
<h:form>
<p:commandButton action="#{Bean1.buttonPressed}" value="Do Work"/>
</h:form>
Bean2:
#ManagedBean()
#SessionScoped
public class Bean2 implements Serializable {
#ManagedProperty(value = "#{Bean1}")
private Bean1 b1;
//getter/setter is here
public String doWorkOnSubmit() {
//Access important Properties from bean1
b1.getFoo()
}
}
Now I have two Problems
1.) How to call "doWorkOnSubmit" if the button in Bean1 is pressed? I can't use the constructor because it's SessionScoped and I don't know how to call doWorkOnSubmit un submit
2.)The managed property "b1" is sometimes null
Since on clicking of Do Work button you are calling Bean1.buttonPressed() action method you can call Bean2s doWorkOnSubmit() by injecting Bean2 in Bean1.
Here is your code altered:
#ManagedBean()
#SessionScoped
public class Bean1 implements Serializable {
//Here are some important Properties
/*
* Inject Bean2 here. since both beans are session scoped,
* there ain't gonna be any problem in injection.
*/
#ManagedProperty(value = "#{Bean2}")
private Bean2 b2;
//GETTER SETTER for b2
public String buttonPressed() {
//Here you will be invoking injected managed beans method.
b2.doWorkOnSubmit();
return "bean2.xhtml";
}
}
I know I can put/get session scope variables like this.
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().put(SESSION_KEY_SOME, some);
Then can't I access the value like this?
#ManagedBean
#SessionScoped
public class SomeOtherBean {
#ManagedProperty("#{sessionScope.some}")
private Some some;
}
The value is null.
#ManagedProperty runs during creation/instantiation of the #ManagedBean.
So, when the #ManagedBean is created before the #{sessionScope.some} is set for first time, then it will still remain null in the #ManagedBean. It will only work when #ManagedBean is created after the #{sessionScope.some} is set for the first time.
There are basically three ways to achieve the desired behavior.
Replace private Some some by externalContext.getSessionMap().get("some").
#ManagedBean
#SessionScoped
public class SomeOtherBean {
public void someMethod() {
Some some = (Some) FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap().get("some");
// ...
}
}
Replace #SessionScoped by #RequestScoped.
#ManagedBean
#RequestScoped
public class SomeOtherBean {
#ManagedProperty("#{sessionScope.some}")
private Some some;
// ...
}
Replace externalContext.getSessionMap().put("some", some) by directly setting it as bean property.
#ManagedBean
public class SomeBean {
#ManagedProperty("#{someOtherBean}")
private SomeOtherBean someOtherBean;
public void someMethod() {
// ...
someOtherBean.setSome(some);
}
// ...
}
See also:
How to choose the right bean scope?
I have this SessionScoped bean:
#ManagedBean
#SessionScoped
public class LoginBean implements Serializable {
/**
* Creates a new instance of LoginBean
*/
public LoginBean() {
this.usuario = new Usuario();
}
private Usuario usuario;
//getter & setter
}
The Usuario class:
public class Usuario {
public Usuario() {
}
private String password;
private String nombre;
private int idPlanta;
private int nivel;
private String idUsuario;
//getters & setters
}
And I want to get the value of the property idPlanta from the SessionScoped bean (LoginBean) here (in the constructor) see the comments:
#ManagedBean
#ViewScoped
public class PrincipalBean implements Serializable {
public PrincipalBean() {
System.out.println(this.login.getUsuario().getIdPlanta());
//AT THIS POINT THE VALUE OF idPlanta IS 0 but in the session I have 1...
//Method that uses the idPlanta value as a parameter
}
#ManagedProperty(value = "#{loginBean}")
private LoginBean login;
public LoginBean getLogin() {
return login;
}
public void setLogin(LoginBean login) {
this.login = login;
}
}
But when I show the value in the view it shows the value that really is in the Session idPlanta = 1. I dont understand why I cant get the value of that property in the constructor of that ViewScoped bean (PrincipalBean). I show the value in the view here(I know I can get it directly fron the LoginBean but this is just to show that the property login in PrincipalBean has the Session value):
<h:outputText class="titulo" value="Bienvenido(a) #{principalBean.login.usuario.nombre} Planta #{principalBean.login.usuario.idPlanta}" />
The value of idPlanta in PrincipalBean is very important because I use it as a method parameter to show more info when the view is showed.
Please help me. I still learning JSF.
You need to be using these values after the bean has been constructed. When your constructor is called, your bean has net yet been initialzed - therefore the injections have not yet happend. Using the #PostConstruct method you will be able to access the desired values from the injected objects.
For example :
#ManagedBean
#ViewScoped
public class PrincipalBean implements Serializable {
public PrincipalBean() {
}
#PostConstruct
public init() {
System.out.println(this.login.getUsuario().getIdPlanta());
//AT THIS POINT THE VALUE OF idPlanta IS 0 but in the session I have 1...
//Method that uses the idPlanta value as a parameter
}
#ManagedProperty(value = "#{loginBean}")
private LoginBean login;
public LoginBean getLogin() {
return login;
}
public void setLogin(LoginBean login) {
this.login = login;
}
}
See Also
Why use #PostConstruct?
Injecting Managed Beans In JSF 2.0
JSF injection with managed property, good pattern?
I'm trying to inject a ManagedBean in my FacesConverted the following way:
#ManagedBean
#RequestScoped
#FacesConverter(forClass = Group.class)
public class GroupConverter implements Converter {
#ManagedProperty("#{groupService}")
private GroupService groupService;
#Override
public Group getAsObject(FacesContext context, UIComponent arg1,
String groupName) {
return groupService.findGroupByName(groupName);
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object group) {
return ((Group) group).getName();
}
public GroupService getGroupService() {
return groupService;
}
public void setGroupService(GroupService groupService) {
this.groupService = groupService;
}
}
The problem is that groupService isn't being injected and I get a NullPointerEx. Shouldn't it be autowired automatically since it's also a ManagedBean? It all works when I change "getAsObject" to "return new Group();" obviously.
Any ideas?
It is likely that you are not resolving the managed bean name.
#ManagedBean(name = "myConverter")
#RequestScoped
#FacesConverter(value = "myConverter")
public class MyConverter implements Converter {
For example, consider these two components:
<h:inputText converter="myConverter" value="#{foo.prop}" />
<h:inputText converter="#{myConverter}" value="#{bar.prop}" />
When the converter is set on the first component, it will be created by Application.createConverter. A converter is not a managed bean. The same rules apply if you match a converter by type.
In the second component, a value expression is used to return a class that implements Converter. This uses the usual managed bean mechanisms. In this case, the #FacesConverter annotation is irrelevant.
I have this SearchBean:
#ManagedBean(name = "searchBean")
#RequestScoped
public class SearchBean implements Serializable
{
private String input = null;
// getter methods
public String getInput() {
return input;
}
// setter method
public void setInput(String input) {
this.input = input;
}
public String Submit() {
return null;
}
}
Can I inject it into another bean using #ManagedProperty. For example:
#ManagedBean(name = "bookBean")
#RequestScoped
public class BookBean implements Serializable
{
#ManagedProperty(value = "#{searchBean}")
private SearchBean searchBean;
#PostConstruct
public void init()
{
System.out.println("Value: " + searchBean.getInput());
}
public SearchBean getSearchBean() {
return searchBean;
}
public void setSearchBean(SearchBean searchBean) {
this.searchBean = searchBean;
}
}
And the Facelet (search.xhtml):
<h:form id="formSearch">
<h:commandButton value="Search" action="#{searchBean.Submit}" />
</h:form>
UPDATE: I have search.xhtml inserted into book.xhtml via a ui:insert component as follow:
<h:form id="formBooks">
<ui:insert name="search">
<ui:include src="/templates/common/search.xhtml"/>
</ui:insert>
</h:form>
The searchBean.getInput() method above should return a value as a result of a form's submission. Is the above method of injection possible?
I assume that SearchBean.input will be bound to an input field:
public class SearchBean implements Serializable {
private String input = null;
Something like this:
<h:inputText value="#{searchBean.input}" />
If so, then this will be null:
#PostConstruct
public void init()
{
System.out.println("Value: " + searchBean.getInput());
}
But, assuming a value has been set, it will not be null when this method is invoked:
public String Submit() {
return null;
}
Image from Richard Hightower's JSF for nonbelievers: The JSF application lifecycle.
The reason is due to how the JSF lifecycle works:
When #{searchBean...} is first resolved and found not to exist:
The bean is instantiated
Any dependency injections are performed (there aren't any in this case)
#PostConstruct method is invoked
The bean is placed into scope
Assuming the Apply Request Values and Validations phases succeed, SearchBean.setInput(String) is invoked in the Update Model Values phase
SearchBean.Submit() is invoked in the Invoke Application phase
This process is defined in the JSF specification.
Now, if SearchBean.input were injected directly from the parameter map, it would not be null during #PostConstruct:
#ManagedProperty(value = "#{param.someParamName}")
private String input;
However, there aren't any real advantages to this - you're skipping any input validation and you can't use SearchBean.input as a field binding because it will be overwritten in the Update Model Values phase.
The SearchBean.Submit() method is where your application logic for performing the search should go.