WebSphere Portal Server - Session sharing between portlets and servlets/jsp

This is Interesting: Free IT Magazines  
Home > Archive > WebSphere Portal Server > May 2007 > Session sharing between portlets and servlets/jsp





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Session sharing between portlets and servlets/jsp

2007-03-21, 1:26 pm

I am trying to implement file download from a portlet (download a generated Excel document). As I understand the portlets can not kick off browser download because they are not allowed to change the content type to anything other then HTML and WML (I trie
d that already and got illegal argument exception).

I am writing JSR-168 portlet on WebSphere Portal 6.0. JSR-168 specification clearly states that sharing the session should be possible: "The PortletSession must store all attributes in the HttpSession of the portlet application. A direct consequence of th
is is that data stored in the HttpSession by servlets or JSPs is accessible to portlets through the PortletSession in the portlet 10 application scope.cxiii Conversely, data stored by portlets in the PortletSession in the portlet application scope is acce
ssible to servlets and JSPs through the ttpSession.".

My plan is to have a button on the portlet named "Download As Excel". When the user clicks the button, I'll open a new browser window pointing to a JSP page. That JSP page would get the Java collection of rows from the HttpSession, generate Excel spreadsh
eet and write it into the response.

So my two questions are:

1. How do I build a URL to the JSP page that would stream binary content? It's packaged in the same war file.

2. How do I access the portlet session data from that JSP page?

2007-03-21, 7:21 pm

OK, I got no replies but I have implemented a working solution myself.

1. Building a URL was relatively easy. In my FacesPortlet's processAction I used the following code:
String url = request.getContextPath() + "/jsp/downloadBinary.jsp";
url = response.encodeURL(url);
response.sendRedirect(url);

2. The session sharing worked as advertised by JSR-168. Setting an attribute value in a portlet session using PortletSession.APPLICATION_SCOPE scope makes it available to servlets and JSPs deployed in the same WAR. No magic there.

There were a few gotchas in the approach. First, sendRedirect() was throwing an exception saying it's in illegal state. I had to add a call to
FacesContext.getCurrentInstance().responseComplete() in my faces bean action method to allow redirecting.

sendRedirect() method is available on the portlet level, but the binary data to be streamed out as Excel spreadsheet was available at the faces bean level. So I set a request attribute in the faces bean, and check for it in the portlet. If the flag is set
, the portlet does a redirect:

public void processAction(ActionRequest request, ActionResponse response) throws PortletException {

super.processAction(request, response);

// Check to see if we should redirect for binary downloads
String fileName = (String) request.getAttribute(WebConstants.DOWNLOAD_FILE_NAME);
if (fileName != null) {
logger.debug("Setting session attributes for download of " + fileName);
try {
String url = request.getContextPath() + "/jsp/downloadBinary.jsp";
url = response.encodeURL(url);
response.sendRedirect(url);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}

My downoadBinary.jsp has the following code:

String fileName = (String) request.getSession().getAttribute(WebConstants.DOWNLOAD_FILE_NAME);
if (fileName != null) {
String contentType = (String) request.getSession().getAttribute(WebConstants.DOWNLOAD_CONTENT_TYPE);
byte[] bytes = (byte[]) request.getSession().getAttribute(WebConstants.DOWNLOAD_BYTES);

response.setContentType(contentType);
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
response.setHeader("Cache-Control", "max-age=600");
response.setContentLength(bytes.length);
ServletOutputStream stream = response.getOutputStream();
stream.write(bytes);
stream.flush();
stream.close();
}
else {
out.print("<b>Missing request parameter <i>" + WebConstants.DOWNLOAD_CONTENT_TYPE + "</i></b>");
out.print("<p>Available parameters:<br>");
Enumeration names = request.getSession().getAttributeNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
out.print("name = " + name + "=" + request.getSession().getAttribute(name) + "<br/>");
}
}

oliver

2007-03-22, 7:31 am

I had tried to do this way. In fact, the downoadBinary.jsp is running in portal container, not servlet container. So the idea I don't agree.
enough is never enough
Michael Harris

2007-05-02, 1:33 pm

I have a JSP file that outputs binary data in the theme... In my initial
versions, the binary data was getting across the HTTP stream to the
browser, but I was still getting an exception in the logs. The problem
was that the generated _jspservice() method created when the JSP file is
compiled was creating a print writer on the output stream. Do you get
the following stack trace in the logs when your JSP file is called?

[5/2/07 11:48:44:148 EDT] 00000072 ServletWrappe E SRVE0068E: Could not
invoke the service() method on servlet <<<path to your JSP file here>>>.
Exception thrown : java.lang.IllegalStateException: SRVE0199E:
OutputStream already obtained
at com.ibm.ws.webcontainer.srt.SRTServletResponse.getWriter(SRTServletRe
sponse.java:478)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java(In
lined Compiled Code))
at org.apache.jasper.runtime.JspWriterImpl.write(JspWriterImpl.java(Comp
iled Code))


My solution to the problem was to avoid calling the _jspservice() method
completely by making the servlet generated from the JSP file extend
HttpServlet directly instead of the default. How did you avoid the
stacktrace?

<%@ page session="false" buffer="none"
extends="javax.servlet.http.HttpServlet" %>
<%!

public void doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
{
...
response.setContentType("image/gif");
response.setContentLength(gifDataBytes.length);
javax.servlet.ServletOutputStream sos = response.getOutputStream();
sos.write(gifDataBytes);
sos.flush();
sos.close();
...
}
%>
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com