Get Session Scoped Bean data in another ManagedBean - jsf-2

I am trying to get session scoped bean data in another Managed bean. When I am doing that value is coming as null and giving java.lang.NullPointerException error. I am new to JSF so keep in mind that I might be missing simple thing.
Here is the SessionScoped Bean
#ManagedBean
#SessionScoped
public class UserSessionBean {
private superProcessId;
//getter setter and other code
}
Here is the Managed Bean I am trying to get this data
#ManagedBean
public class AddProcessBean {
#ManagedProperty(value="#{UserSessionBean}")
private UserSessionBean sessionData;
//Getter Setter for sessionData
public UserSessionBean getSessionData() {
return sessionData;
}
public void setSessionData(UserSessionBean sessionData) {
this.sessionData = sessionData;
}
public void addAction() {
System.out.println(getSessionData().getSuperProcessId());
}
}

Your value is not good in #ManagedProperty. Use:
#ManagedProperty(value="#{userSessionBean}")
Default name for bean is same as class name with lower first letter. Also scope of your bean whose managed property is should be session or lower (view, request).

Related

JSF application scoped bean not injectable as managed property of ADF request scoped bean

EDIT: This is an ADF application which uses JSF 2.0.
I have an application-scoped managed bean which I am referencing in the managed property of a request-scoped bean. I am getting a NullPointerException when trying to access the app-scoped bean within the PostConstruct method of the request-scoped bean. I am not sure whether I am not understanding some fundamentals about when an app-scoped bean is available to a request-scoped bean, or whether I just have a mistake in my implementation.
App-scoped bean:
#ManagedBean(eager=true)
#ApplicationScoped
public class SecurityApplication {
public String test() {
return "test result";
}
#PostConstruct
public void init() {
System.out.println("In SecurityApplication.init");
}
}
EDIT: This is configured as a request-scoped managed bean in the adfc-config.xml file. This appears to be the problem since I have specified that the bean be managed by ADF, but used the JSF ManagedProperty annotation.
Request-scoped bean:
public class UserSecurityCompanies {
#ManagedProperty(value="#{securityApplication}")
private SecurityApplication securityApplication;
#PostConstruct
public void init() {
System.out.println("In UserSecurityCompanies.init");
System.out.println("SecurityApp.Test():" + getSecurityApplication().test());
}
public SecurityApplication getSecurityApplication() {
return securityApplication;
}
public void setSecurityApplication(SecurityApplication securityApplication) {
this.securityApplication = securityApplication;
}
}
The app-scoped bean is initialized during deployment of the app, but the NPE is thrown when getSecurityApplication().test() is called.
Steve

Managed property value not updated when both beans are of same scope

I am seeing this strange behavior when using #ManagedProperty. I have 2 beans:
UserManager (SessionScoped)
#ManagedBean
#SessionScoped
public class UserManager extends BaseBean implements Serializable
{
private static final long serialVersionUID = 1861000957282002416L;
private User currentUser;
public String login()
{
// set value of currentUser after authentication
}
public User getCurrentUser() {
return currentUser;
}
public boolean isLoggedIn() {
return getCurrentUser() != null;
}
}
CartBean (ALSO SessionScoped)
...
import javax.faces.bean.ManagedProperty;
...
#ManagedBean
#SessionScoped
public class CartBean extends BaseBean implements Serializable
{
#ManagedProperty(value = "#{userManager.loggedIn}")
private boolean loggedIn;
public void updateCart(Movie selectedMovie)
{
if (!loggedIn) {
return;
}
System.out.println("UPDATE CART REQUEST");
int id = selectedMovie.getMovieID();
if (cart.containsKey(id)) {
cart.remove(id);
}
else {
cart.put(id, selectedMovie);
}
}
public void setLoggedIn(boolean loggedIn) {
this.loggedIn = loggedIn;
}
}
After logging in successfully, the value of loggedIn still remains false.
However, if I change the scope of CartBean to #ViewScoped, the value of loggedIn gets updated and I see the sysout.
As per my understanding and also after reading various articles, one can inject a managed bean or its property only if it is of the same or broader scope. But the "same scope" case does not seem to work in my code. What am I missing here?
I am using:
Mojarra 2.1.16
Spring 3.2
Hibernate 4.1
Tomcat 7.0.37
#ManagedProperty annotation can only provide static injection, which means that the annotated property will get injected when and only when the holding #ManagedBean is instantiated.
When you deploy your application, I believe your CartBean was referenced right at the beginning through things like the View cart button, etc. As a consequence, the injection took place too early and since the bean is #SessionScoped, you will carry the initial false value till the end of time :).
Instead of injecting only the boolean field, you should, instead, inject the whole UserManager bean:
#ManagedBean
#SessionScoped
public class CartBean extends BaseBean implements Serializable {
#ManagedProperty(value = "#{userManager}")
private UserManager userManager;
public void updateCart(Movie selectedMovie) {
if (!userManager.isLoggedIn()) {
return;
}
...
}
}
The solution is using Omnifaces it worked for me each time the value change you will get the new value
#ManagedBean
#ViewScoped
public class CartBean extends BaseBean implements Serializable {
private boolean loggedIn;
public void updateCart(Movie selectedMovie) {
loggedIn=Faces.evaluateExpressionGet("#{userManager.loggedIN}");
if (!userManager.isLoggedIn()) {
return;
}
...
}
}

Auto-instantiate session-scoped bean from view-scoped bean

Every time I try to inject a session-scoped bean into my view-scoped beans, I get a NullPointerException when calling said bean. This problem is directly related to auto -instantiate a session bean?
Here is what I tried so far:
faces-config.xml
<managed-bean>
<managed-bean-name>sessionBean</managed-bean-name>
<managed-bean-class>com.example.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>viewBean</managed-bean-name>
<managed-bean-class>com.example.ViewBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
<managed-property>
<property-name>sessionBean</property-name>
<property-class>com.example.SessionBean</property-class>
<value>#{sessionMBean}</value>
</managed-property>
</managed-bean>
SessionBean.java:
package com.example;
public class SessionBean {
public SessionBean() {
System.out.println("Session is instantiated.");
}
public void sayHello() {
System.out.println("Hello from session");
}
}
ViewBean.java:
package com.example;
public class ViewBean {
private SessionBean sessionBean;
private String text = "Look at me!";
public ViewBean() {
System.out.println("View bean is instantiated.");
sessionBean.sayHello();
}
public SessionBean getSessionBean() {
return sessionBean;
}
public void setSessionBean(SessionBean sessionBean) {
this.sessionBean = sessionBean;
}
public String getText() {
return text;
}
}
and the relevant content of index.xhtml:
<f:view>
<h:outputText value="#{viewBean.text}"/>
</f:view>
And this is what I get:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.example.ViewBean.
...
Caused by: java.lang.NullPointerException
at com.example.ViewBean.(ViewBean.java:12)
This runs (or rather doesn't run) on weblogic-10.3.6 with the shipped jsf-2-0.war deployed as a library.
What am I doing wrong here? I'm hoping this is not a container bug...
You cannot access the #SessionScoped bean in the #ViewScoped constructor. The #SessionScoped bean will be set AFTER the constructor of the #ViewScoped bean has been called.
Use the #PostConstruct annotation in some kind of init method to access the #SessionScoped bean.
public ViewBean() {
System.out.println("Constructor viewbean");
}
#PostConstruct
public void init() {
sessionBean.sayHello();
}
Further Links:
Why use #PostConstruct?
Spring Injection - access to the injected object within a constructor

Can i use HttpSession object as an instance variable in Managed Bean. Getting NotSerializableException exception

I am using HttpSession as an instance variable like
#ManagedBean
#ViewScoped
public class CountryPages_Detail {
private HttpSession session;
public CountryPages_Detail() {
session = ConnectionUtil.getCurrentSession();
} //end of constructor
public String preview() {
session.setAttribute("countryDetailImageNames", imageNames);
session.setAttribute("countryDetailImages", images);
session.setAttribute("countrySummary", countrySummary);
return "countryPages_View?faces-redirect=true";
} //end of preview()
} //end of class CountryPages_Detail
ConnectionUtl Class:
public static HttpSession getCurrentSession() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletRequest httpServletRequest = (HttpServletRequest) externalContext.getRequest();
HttpSession currentSession = (HttpSession) externalContext.getSession(false);
if (currentSession != null) {
return currentSession;
} else {
return null;
}
} //end of getCurrentSession()
I want to ask is this right way? Actually i was using in my web.xml
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
But when i changed it to <param-value>client</param-value>, then first i got the exception that one of my class is not serializable, after making it serializable now i am getting exception that
SEVERE: Error Rendering View[/index.xhtml]
java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
....
When using server it was running fine. Why? I want to ask when we server in param-valuethen all our managed bean that are in viewScope(#ViewScoped) reside on server, and when we change it to client in then all our #ViewScoped managed bean reside on client? Also if my beans are not in #ViewScoped, then does javax.faces.STATE_SAVING_METHOD element create any difference? Means STATE_SAVING_METHOD option relates to only #ViewScoped or it also effects #RequestScope or #SessionScopr or other scopes?
thanks
You should absolutely not get hold of external context resources like HttpSession as an instance variable. Just retrieve it in the threadlocal scope. You can use ExternalContext#sessionMap() to manage the session attribute map without the need to have javax.servlet imports in your JSF code (which is usually a sign that you're doing things the wrong or clumsy way, whereby you're completely working your way around JSF without utilizing JSF's powers).
public String preview() {
Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
sessionMap.put("countryDetailImageNames", imageNames);
sessionMap.put("countryDetailImages", images);
sessionMap.put("countrySummary", countrySummary);
return "countryPages_View?faces-redirect=true";
}
Better, however, is to create a session scoped managed bean. You've there namely some strange and rather procedural and non-OO design.
#ManagedBean
#SessionScoped
public class Country {
private List<Something> detailImageNames;
private List<Something> images;
private Something summary;
// ...
}
which you use as follows inside CountryPagesDetail:
#ManagedProperty("#{country}")
private Country country;
public String preview() {
country.setDetailImageNames(imageNames);
country.setDetailImages(images);
country.setSummary(summary);
return "countryPages_View?faces-redirect=true";
}
It's available by #{country.detailImageNames} and so on.

Session Bean being lost?

The first "nonpostback" request to viewBean, someValue property in sessionBean is null.
Now, in a postback request, I am setting a user input to someValue. The problem is that someValue is always null in any "nonpostback" request.
Here is my code:
#ManagedBean
#ViewScoped
public class ViewBean implements Serializable {
#ManagedProperty(value = "#{sessionBean}")
private SessionBean sessionBean;
private String inputText;
#PostConstruct
public void init() {
if (sessionBean.getSomeValue() != null) // ALWAYS NULL
doSomething(sessionBean.getSomeValue());
}
private void doSomething(String s) {}
public void action(final ActionEvent ae) {
sessionBean.setSomeValue(getInputText());
doSomething(getInputText());
}
GETTERS/SETTERS
}
#ManagedBean
#SessionScoped
public class SessionBean implements Serializable {
private String someValue;
GETTER/SETTER
}
I feel I am doing something wrong. I am using Mojarra 2.1.2
Any advice is appreciated. Thank you.
UPDATE:
Using evaluateExpressionGet on both methods (init and action) works fine:
FacesContext context = FacesContext.getCurrentInstance();
SessionBean sessionBean = context.getApplication().evaluateExpressionGet(context,
"#{sessionBean}", SessionBean.class);
This is a known issue:
SessionScoped bean inside a ViewScoped bean is resolved as different bean depending on the expression used
I just changed the state saving method in my web.xml:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
I use GAE (Google App Engine) and need to set javax.faces.STATE_SAVING_METHOD to client. This problem can have workaround. After the action, just call refreshSession() with new value force the session object persist
protected void refreshSession(){
saveSession(CeaConst.SESSION_ATTR_NAME_LAST_REFRESH_TIME, new java.util.Date());
}

Resources