How to use HTTP Session Scope in portlets ? - jsf

In my application there are 5 portlets accessing same bean class which is in session scope. My problem is, whenever I open a portlet, managed bean initializes. Managed bean should be initialize once in a session. In my case bean initializing 5 times. Can anyone tell me what is the root cause of that problem?
Here is my bean :
#ManagedBean(name="userManagementBean")
#SessionScoped
public class UserManagementBean {
public UserManagementBean() {
System.out.println("In getter setter bean");
sName=userManagementHelper.findScreenName();
directReport=new DualListModel<String>();
addUserToGroupDual=new DualListModel<String>();
addUserToGroupDual.getSource().clear();
addUserToGroupDual.getTarget().clear();
............

When you annotate your beans with #SessionScoped in Portlet application it is mapped to something as "Portlet Instance Session". This means that this bean will live in session of that portlet, and each portlet has its own session. There is something called "Global Session" which is session shared across all portlets, but as far as I know there is not such annotation in JSF.

JSR286 has user session based scope but it would depend on your portal server if it has the implementation for this as a Custom Scope for JSF.
I know for sure that Websphere portal 8.x supports this.
In Websphere portal 8.x you can specify your managed bean like,
#ManagedBean(name="userManagementBean")
#CustomScoped("#{portletApplicationSessionScope}")
public class UserManagementBean {
...
}
Have a look into your portal server documentation to see if it supports that.
You can use Apache JSF portlet bridge as you have updated that you are using liferay ,
It will expose Application Session Scope as EL,
Add it to application scope in portlet A
PortletSession session = request.getPortletSession();
session.setAttribute("name",name.getValue().toString(),PortletSession.APPLICATION_SCOPE);
and use in portlet B
PortletSession session = request.getPortletSession();
String value = session.getAttribute("name", PortletSession.APPLICATION_SCOPE).toString();
Your xhtml ,
<h:inputText id="itName"
required="true"
value="#{httpSessionScope.name}"/>

Related

Inject an application scoped managed bean in a websocket

I'm developing a real time application. I have websockets and application scoped managed bean. I'm trying to access the application scoped managed bean from a websocket but I can't. Is this possible?
This is my websocket and managed bean (application scoped):
#ServerEndpoint("/mediador")
#ManagedBean(eager = true)
#ApplicationScoped
public class Mediador implements Serializable {
#ManagedProperty(value = "#{aplicacion}")
private Aplicacion aplicacion;
...
And my "Aplicacion" managed bean:
#ManagedBean(eager = true)
#ApplicationScoped
public class Aplicacion implements Serializable {
...
If I try to access in Mediador class to de managed property "aplicacion" it's null so I get a NullPointerException.
Thanks
This is really not right.
#ServerEndpoint("/mediador")
#ManagedBean(eager = true)
#ApplicationScoped
public class Mediador implements Serializable {
WS (JSR-356 WebSocket) API and JSF API are completely independent from each other. They know nothing from each other and won't take mixed annotations from each other into account.
Effectively, you end up with two instances of the class. One as a WS managed server endpoint as available by ws://.../mediador, and one as a JSF managed bean as available by #{mediador}. The #ManagedProperty is only recognized by JSF managed bean facility and it'll work in the JSF managed bean instance only.
Use CDI instead. It works across the entire Java EE web application. Not only in WebSocket endpoints, but also in JSF managed beans, WebServlets, WebFilters, WebListeners, JAX-RS resources, JAX-WS resources, etcetera. Eventually, JSF managed bean facility will be deprecated in favor of CDI. This will happen in Java EE 9 or perhaps already 8.
#ServerEndpoint("/mediador")
public class Mediador { // Shouldn't be serializable!
#Inject
private Aplicacion aplicacion;
// ... (no getter+setter needed!)
}
#Named
#ApplicationScoped // javax.enterprise.context
public class Aplicacion { // Shouldn't be serializable!
// ...
}
Unrelated to the concrete problem: implementing websockets in JSF rightly is not exactly trivial, certainly not if you'd like to take into account JSF session and view scopes, and would like to be able to target a specific user during push. You'd better look at an existing push component. See also How can server push asynchronous changes to a HTML page created by JSF?

How to get application scoped managed bean on servlet

I have a bean that I configured to be application scoped in faces-config.xml as below:
<managed-bean eager="true">
<managed-bean-name>communicationCRCList</managed-bean-name>
<managed-bean-class>com.ingdirect.edeal.bean.CommunicationCRCListBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
That been is loaded when the app starts by the call of the INIT() method on a different class.
The app starts, the class is loaded and create the bean calling the init method.
As it's an application scoped bean, it should be accessible from everywhere.
In my case, I would like to get that bean in a servlet. I read that all the application scoped managed beans are loaded in the servletContext. In order to get that bean, I tried the following in my servlet:
CommunicationCRCListBean CommunicationCrcListBean = (CommunicationCRCListBean) getServletContext().getAttribute(COMMUNICATION_LIST_CRC_BEAN);
For information, COMMUNICATION_LIST_CRC_BEAN = communicationCRCList--> name of the bean. Unfortunatly, I get null....
I can't figure out what's wrong... Does somebody has an idea ?

How to initialise a Managed Bean in request scope from a servlet

I have a servlet that will navigate to a JSF page upon some conditions using ExternalContext.redirect.
I need to initialise a Managed Bean in this Servlet and set it in request scope so that my JSF page can directly access the Managed Bean's property and display them on the page load.
I had seen posts that sets the bean using getServletContext()
Like,
getServletContext().setAttribute("beanName",new Bean())
it works.But this approach will be setting the bean in application scope instead of request scope.
Also i tried the following:
request.setAttribute("beanName",new Bean())
it doesnt work
So pls let me know if there is any way to set /initialise a managed bean in a request scope
If it's a request scoped bean, use HttpServletRequest#setAttribute()
BeanName beanName = new BeanName();
request.setAttribute("beanName", beanName);
If its a session scoped bean,
request.getSession().setAttribute("beanName", beanName);

Access session scoped JSF managed bean in web filter

I have SessionScoped bean called userSession to keep track of the user ( username, ifLogged, etc). I want to filter some pages and therefore I need to access the bean from the webFilter I created. How do I do that? I looks like its even impossible to import the bean to be potenitally visible.
Under the covers, JSF stores session scoped managed beans as an attribute of the HttpSession with the managed bean name as key.
So, provided that you've a #ManagedBean #SessionScoped public class User {}, just this should do inside the doFilter() method:
HttpSession session = ((HttpServletRequest) request).getSession(false);
User user = (session != null) ? (User) session.getAttribute("user") : null;
if (user != null && user.isLoggedIn()) {
// Logged in.
}
Or, if you're actually using CDI instead of JSF to manage beans, then just use #Inject directly in the filter.
See also:
Get JSF managed bean by name in any Servlet related class
Prevent accessing restricted page without login in Jsf2
As an alternative you can use CDI-beans and inject your sessionbean normally.

JSF2.0 PostConstructApplicationEvent managed bean is null

We have JSF2.0 in Tomcat6.0 , need to initialize a ApplicationScope Bean while web server is started.
I tried using the PostConstructApplicationEvent processEvent method to initialize the Bean , but the managed bean from faces-config.xml is returning null.
Is there any other better way to instantiate the bean after startup?
Remove any faces-config.xml declarations related to the bean (they will otherwise override the JSF 2.0 annotations) and then annotate the bean with #ManagedBean(eager=true) as follows:
#ManagedBean(eager=true)
#ApplicationScoped
public class Bean {
// ...
}
This way the bean will always be instantiated on JSF webapp startup, without the need to view any page. You can then do the initialization job in the constructor and/or #PostConstruct of the bean.

Resources