HttpSession is null (randomly) when retrieved from HttpServletRequest using ExternalContext - jsf

I have following code to retrieve HttpSession from HttpServletRequest using ExternalContext in our Icefaces(1.8.2) & JSF(1.2) based Liferay environment :
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest httpServletRequest = (HttpServletRequest) (externalContext.getRequestMap().get("com.liferay.portal.kernel.servlet.PortletServletRequest");
HttpSession httpSession = httpServletRequest.getSession();
The above code snippet is working fluently for Liferay 6_1_0_CE_GA1 as httpSession is always populated.
But, the same code in Liferay 6_2_1_CE_GA2, I am randomly getting httpSession as null. Couldn't figure out, what the difference can be!
I have also, tried to get httpServletRequest using PortalUtil.getOriginalServletRequest and then getting httpSession from it, but that doesn't resolve the issue.

When I need access to HttpServletRequest from a Liferay portlet, I have to use this:
HttpServletRequest httpServletRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
renderRequest is an object extended from the PortletRequest class. From your code, you can get the PortletRequest object this way:
PortletRequest portletRequest = (PortletRequest) externalContext.getRequest();
So, the resulting code should be:
PortletRequest portletRequest = (PortletRequest) externalContext.getRequest();
HttpServletRequest httpServletRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(portletRequest));
Hope this helps. Regards!

First of all: Please also try this on 6.2 GA6, which is out for a month now. In case this is a bug it might already be fixed during one of the later versions - the version you're using is almost 2 years old now.
Further, there's nothing that I'm aware of in the specification that allows access to the underlying HttpServletRequest. That's not to say that this is impossible (because it obviously is possible) but to say that behaviour might change, because you're outside of the specs.
I'd recommend to inspect the objects you get with a debugger and check if they're wrappers around the original servlet container's request or the actual container's objects. Also, compare if these requests are directed to the portal (check the URL) or to the portlet itself - as they're deployed in different contexts, they'll have different sessions (or one might have sessions while the other doesn't)

Related

Need to download Excelsheet in ADF using Apache POI

I am working with ADF. I have seen so many posts on downloading excelsheet using java and tried number of ways.
They suggest to use Servelet. But in my case, I am using ViewObjects and iterators in my managed bean. Workbook object (With all the data) will be formed in managed bean and I am able to save the file locally in my desktop, but on other desktop it's either not saving or saving and opening on my desktop.
I tried servelet:
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();
HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
response = (HttpServletResponse) fc.getExternalContext().getResponse();
// ADFUtils.setSessionAttribute("WorkSheetObj", workBook);
RequestDispatcher dispatcher = request.getRequestDispatcher("/excelsheetdownloadServlet");
response = (HttpServletResponse) fc.getExternalContext().getResponse();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "inline;filename=inline.xls");
workBook.write(response.getOutputStream());
But here I have to get object of workBook which is formed in managed bean, so it is not working.
I directly tried to write a code in my managed bean.
But that also didnt help me. Please suggest me on downloading the excelsheet written from Apache POI on client machine.

Transfer Java object between JSF pages

I tried to implement flash in JSF. It's working well if I have to transfer Java object between pages in one session. But I have a spacial case which I need to solve.
I have a submit form where user enters personal data. Then he opens second page which is used to open payment gateway(paypal) page. When the payment is applied Paypal redirects the user back to the web site in a new web page.
I need some way to transfer the Java object data between the first and the last page. Is there any solution?
I'm using JSF 2.2.6 with Tomcat 8.
I guess the redirect of paypal to your site create a new session, if this is the case all you have to do is create a DTO object and store into BD with session ID using serialization Java Serializable Object to Byte Array
But if paypal call on same session all you got to do is get the object from the session like this
FacesContext facesContext = getFaceContext();
Application app = facesContext.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesContext.getELContext();
ExternalContext externalContext = facesContext.getExternalContext();
HttpSession session = (HttpSession) externalContext.getSession(true);
session.setMaxInactiveInterval(-1);
ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
YourBean yourBean = (YourBean) valueExp.getValue("#{yourBean}");
The scope of this bean it must be #SessionScoped

Injecting a session-scoped bean in JSF2

I'm having some difficulty interacting with a Session-scoped managed bean after a user programmatically logs into my web application.
BACKGROUND:
I have a [javax.enterprise.context.]Session-scoped bean named "SessionHelper" where I place a lot of information gathered from the user as he/she uses the application. In my logon page (which is NOT SessionScoped), Here's a sample of what I'm doing:
#Inject SessionHelper theHelper;
....
FacesContext theContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = theContext.getExternalContext();
HttpServletRequest theRequest = (HttpServletRequest) externalContext.getRequest();
....
theRequest.login(username, password);
....
theSession.method(dostuff);
After this section of code is executed, my application redirects into a protected directory and allows the user (based on roles) to perform their job functions.
When I attempt to "#Inject SessionHelper" into any of my protected resources, my understanding is that I should get the specific SessionScoped instance of SessionHelper that has the data set right after the call to login. This should be available to me for as long as the session (for that specific user) is valid. Unfortunately, the instance I'm getting has none of my "theSession.method(dostuff)" in it.
Am I fundamentally misunderstanding the scope here?
The only thing I could potentially see is that the initial #Inject into my login page is not carried over after the session has been created. If this is the case, is there a way to force a re-injection after the session is created?
As always, thank you very much for your help!!

JSF PhaseListener viewId always one behind

Im trying to prevent users to access special pages with a phaselistener. for that reason im trying to figure out on which page they try to access.
but my problem is, i only get the page they where before. not the actual page.
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
System.out.println("test1" + fc.getViewRoot().getViewId());
}
and same here
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
String uri = request.getRequestURI();
System.out.println("uri: " + uri);
}
why is that, and how do i get the pagename the user is trying to access? Not that one that they required one step before, or better the page they are coming from.
It is one step behind because that is the way sequence of HTTP POST request behaves. When you are navigating in JSF application via command buttons each request goes as a post request.
Since you are protecting some resources make sure they are accessed via HTTP GET than you will get exact view id, this can be achieved as
User directly hits the url from address bar of browser.
After a post of jsf app redirect it to the resource instead of simple JSF navigation. POST-REDIRECT-GET pattern falls into this have a look here.
If you are showing some messages after each POST, you might need Flash map for that, which is new feature in JSF2, if you are on JSF1.x hard luck, you can implement flash if you want to.
To conclude catch the view ids on HTTP GET request.
Hope this helps...

get HttpServletResponse from liferay portal

I am trying to get the HttpServletResponse from liferay portal. I am also working with icefaces.
PortletResponse response1 = (PortletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpServletResponse response = (HttpServletResponse)response1;
I get the following Exception:
Caused by: java.lang.ClassCastException: com.liferay.portlet.RenderResponseImpl cannot be cast to javax.servlet.http.HttpServletResponse
Try PortalUtil.getHttpServletResponse(portletResponse)
May be this Helps
Generate PDF File in Portlet
FacesContext will return PortletRequest/Response objects if you are using the portlet bridge.
What are you trying to do with the HttpServletResponse?
If you are trying to generate binary content, this will only work in the Resource phase of a JSR 286 portlet (otherwise you cannot set headers). It will never work in a JSR 168 portlet. If you need to do this in a JSR 168 portlet, you need to use a helper servlet.
In any case, if you are trying to use a third party lib that requires HttpServletResponse for its API, you can use a PortletRequestDispatcher to dispatch to a JSP or a servlet and then use the HttpServletResponse that is available to you there.
Try getting the native response and then casting it:
FilterServletResponseWrapper filterResponse = (FilterServletResponseWrapper) RequestContextHolder.getRequestContext().getExternalContext().getNativeResponse();
HttpServletResponse response = (HttpServletResponse)filterResponse.getResponse();

Resources