tags:

views:

315

answers:

2

I am trying to generate a report document from liferay portlet. The method I am using for report generation is already using OutputStream that i cannot change. Following is the method signature.

public void generateReport(OutputStream outPut);

I am passing output stream to the method using the following line

PortletResponse portletResponse = (PortletResponse)externalContext.getResponse(); HttpServletResponse httpResponse = PortalUtil.getHttpServletResponse(portletResponse);

and then calling the method using the following line

generateReport(httpResponse.getOutputStream());

This runs successfully but nothing happens.

I have to generate a report using the above method in my portlet. Any idea?

A: 

Portlets are supposed to generate snippets of HTML code and stream them to the output stream - so it depends where & when you grab the output stream. It might be that there's already some other HTML (from the theme or another portlet) that has been sent through that stream. Obviously you can't add a word document in the middle of another (html) document.

Please post either the full method or even the whole portlet class where you are refering to the output stream. Is it during action- or render-phase or at a resource-serving method? In a servlet?

Edit: Sorry, with your addition it doesn't become much clearer - there are several topics mixed up. First: Portlets don't have any notion of a button and an ActionListener, so you seem to be utilizing some framework. Even more so some actual code (and context) would be beneficial.

Most important: Keep in mind that you can't just grab an OutputStream and send some Word document to it: Usually portlets are supposed to generate some well-formed HTML snippet, as the output is embedded in a page constructed elsewhere. Read about "portlet resource serving" to learn more about the mechanics when you want to generate content that's not HTML. The fact that you write some report to the output stream and then try to use the same stream to merge some velocity template suggests that something is fundamentally wrong in your example code description.

Some additional hints: Perhaps it's easier to write "just" a servlet. When you're generating a Word document for download it's not necessary to implement a portlet (as it will "just" generate a word document). Once you get this to work you could add the portlet boilerplate, but it might be easier in this environment. Plus, when you're serving a Word document you probably want to set Mimetype and some other metadata (filename, force "download", maybe cache-control headers), so you wouldn't "just" stream the word document to the OutputStream. Maybe the code that you have to use does this, maybe not... hope you know...

Olaf
Due to some limitations, I have posted my response as answer please look at the answer that I have posted.
Sajjad
see my edits. I guess you could edit your own question, right?
Olaf
Have a look at my answer
Sajjad
A: 

What I am doing here is as under.

I have a commandButton on screen to which I have attached an actionListener. When the button is clicked the action Listener invoked and the following lines executes

PortletResponse portletResponse = (PortletResponse)externalContext.getResponse(); HttpServletResponse httpResponse = PortalUtil.getHttpServletResponse(portletResponse);

generateReport(httpResponse.getOutputStream());

generateReport after some business logic executed the following lines.

context.put(...); ... ...

BufferedWriter writer = writer = new BufferedWriter( new OutputStreamWriter(fos));//where fos is outputstream

if (t != null){// t is Velocity template

t.merge(context, writer);//context is VelocityContext

}

writer.flush(); writer.close();

there is no other call after generateReport method. The request finishes after generatReport returns and I expect that it should show me the dialog box but it isn't.

Hope you will get the idea.

Edit: Thanks for your response Olaf

1) First of all I know very well that portlet dont have any notion of button or actionlisteners. Definitly I amd using a framework named Icefaces or whichever it is.

2) It was just my idea to generate document, as initially i donot know about the fact that portlet only display markup and nothjing else. My mistake :).

3) Well I think i already mentioned that I have to use the method and even I cant change it at all. So whatever the code may be, I have to implement the functionality and the code sample I have given is sufficient in that case.

4) I did some research on portlets and found that in JSR 268 'Resource Serving' functionality has been provided but in JSR 168 there is no such support. But the important thing is that the solutions I have found are all JSP dependant and m using xhtml format for UI rendering.

5) What m doing is that I have a portlet displayed transactions and I've got a requirement to provide a 'Print Transactions' button on portlet which will actually print what is displayed on that page. And for that purpose I've provided a method named 'generateReport' which is currently used in old JSP environment i.e having called this method from JSP.

6) I know that the code seems to be fundamentally wrong but having implementing a seperate servlet is another wrong that I will do with the code. I have done research for that and m 85 % close to solution. M thinking about resource serving solution and I dont think that a seperate servlet is much elegant solution.

I will really appreciate any help from your side and I hope that you got some idea what m doing and you should.

Thanks and Regards,

Sajjad