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

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);

Related

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 ?

Get JSF managed bean from session

I have a session scoped managed bean that need to be set from another session managed bean, to do this I do the following
RWIRManagedBean managedBean = new RWIRManagedBean();
managedBean.setRequest(req);
managedBean.setDisplayAppDetailsMode(new Boolean(true));
FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.put("RWIRManagedBean", managedBean);
pageId = ((DoBRServiceViewObj)getConfigMap().
get(ConstantsManager.WebConstants.RWIR_SERVICE_ID)).getServicePageID();
// page id is a jsf page, the belwo is the redirect code
EngineURL engineURL = getRedirectURL(FacesContext.getCurrentInstance().
getExternalContext(),pageId,FacesContext.
getCurrentInstance().getViewRoot().getLocale().getLanguage());
FacesContext.getCurrentInstance().getExternalContext().redirect(engineURL.toString());
But when I call the JSF page associated with this managed bean, it looks like if a new managed bean was created and the one I created does not exist.
My question is , the JSF life cycle is supposed to get the managed bean from the session when it evaluate the JSF page, but why it creates a new one in my case? Any help

How to use HTTP Session Scope in portlets ?

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}"/>

Access ViewScoped ManagedBean from Servlet

Background information: I have a file upload applet in my jsf page. This applet expects an adress where it can send it's POST request. (I can't edit this post request to add more fields or something). The post method of my servlet then stores the file. This job can't be done by a managed bean because the servlet has to be annotated with #MultiPartConfig and I can't add this annotation to the jsf managed bean. In order to force the upload applet to use the same session I added an URL attribute named jsessionId to the post request according to this post. In my servlet I am now able to access session scoped beans.
Now I have a ViewScoped bean where I store some form input data which I want to use in the servlet, since adding those inputs to the post request doesn't work (Applet is a third party project (JUploadApplet) and for some reason it doesn't work to add additional form data).
Now is it possible to access the ViewScoped bean from within the servlet ? If I change the scope into SessionScope I am able to process the input but with ViewScoped I get a NullPointerException if I try to access the bean like this :
UploadBean uploadBean = (UploadBean)request.getSession().getAttribute("uploadBean");
This is not possible. Your best bet is to let the view scoped bean generate an unique key, store itself in the session scope by that key and pass that key as additional parameter to the applet and finally let the servlet access the session attribute by that key.
E.g.
private String sessionKey;
#PostConstruct
public void init() {
sessionKey = UUID.randomUUID().toString();
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(sessionKey, this);
}
#PreDestroy
public void destroy() {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(sessionKey);
}
Let the applet pass the sessionKey as request parameter to the servlet, so that the servlet can do
String sessionKey = request.getParameter("sessionKey");
Bean bean = (Bean) request.getSession().getAttribute(sessionKey);
// ...
Note that instead of the bean itself, you can also just store an arbitrary bean/valueobject/etc.

How could I read a JSF session bean from a filter?

I'm searching but I can't find the answer, I need secure resources based on permissions, I can't use a filter because FacesContext is not initialized before and I need load the permissions in my session bean. Some solution avoiding use a filter? PhaseListener, ViewHandler and ResourceHandler can't capture an URL resource request, for example I need denied this direct access: http://127.0.0.1:8080/test/resources/images/image.jpg
Thx in advance...
JSF stores session scoped managed beans as an attribute of the HttpSession, which in turn is just available in a Filter by HttpServletRequest#getSession().
HttpSession session = ((HttpServletRequest) request).getSession();
SessionBean sessionBean = session.getAttribute("sessionBean");
// ...
Update: as per the comment you seem to be actually using CDI:
my filter is triggered before than JSF, I always get a null value when I use getAttribute. I'm using CDI with 'Named' and 'SessionScoped' annotations on my Bean because I need use a interceptor to implement security
I understood that you were using JSF's own #ManagedBean and the initial answer only applies to that. If your bean is already managed by CDI's #Named, then just use CDI's own #Inject the usual way in the Filter.
#Inject
private SessionBean sessionBean;
In case of JSF #ManagedBean you should just add a if (sessionBean != null) check. It's irrelevant whether the filter is invoked before JSF servlet or not. Once the session bean has been created by JSF, it won't be null in the filter.

Resources