You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Ender Shorty <en...@gmail.com> on 2006/11/10 05:11:19 UTC
Outputing a file to user (correctly getting ahold of the getOutputStream method)
Hello all,
I've searched around the forums attempting to discover a way to output a
file to the user. What I'm trying to do is after creating a pdf file with
JasperReports i'd like to output it to the user. I use Tapestry 4.02. It
looks like the old way was to do something like this...
Make a method like the following a a listener, such as from a DirectLink or
whatever.
(The Document is just a class that holds the file information you want to
send to the user.)
public void downloadAction(IRequestCycle cycle)
{
try
{
HttpServletResponse response =
cycle.getRequestContext().getResponse();
byte[] data = new byte[1024];
FileInputStream in = document.getFileInputstream();
response.setHeader("Content-disposition",
"inline; filename=" +
document.getFileName());
response.setContentType(document.getMimeType());
response.setContentLength(new Long(document.getSize()).intValue());
ServletOutputStream out = response.getOutputStream();
int bytesRead = 0;
while ((bytesRead = in.read(data)) > -1)
{
out.write(data, 0 , bytesRead);
}
in.close();
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Now it output's a pdf file correctly, and everything seems to work
fine, but looking at the log, i get serveral of these:
javax.servlet.ServletException: getOutputStream() has already been
called for this response
Apparently the new correct way is to create a service. Does anyone
have an example of outputing a file with a service?
Thank you very much for any assistance.
Re: Outputing a file to user (correctly getting ahold of the getOutputStream
method)
Posted by Jiří Mareš <Ji...@svt.cz>.
Hi,
it is not much difficult: First the URL to servise is http://your.server/your.app.context/app?service=pdf_report&pdf=xx
where the pdf_report is the name of the service and attribute pdf specified what report to return (you can use any
attributes you want and need).
Then you create the service:
public class PdfReportServise implements IEngineService {
protected HttpServletResponse response;
protected LinkFactory linkFactory;
public void setResponse(HttpServletResponse response) {
this.response = response;
}
public void setLinkFactory(LinkFactory linkFactory) {
this.linkFactory = linkFactory;
}
public String getName() {
return "pdf_service";
}
public void service(IRequestCycle cycle) throws IOException {
... first parse you parameters ...
... generate the report or open the file with report ...
response.setHeader(...); eg. Content-Disposition ...
response.setContentType("application/pdf");
try {
OutputStream os = response.getOutputStream();
... write your data ...
} catch (IOException e) {
throw new ApplicationRuntimeException(e);
}
}
public ILink getLink(boolean post, Object parameter) {
Map params = new HasMap();
params.put("param1", (String) ((Object[]) parameter)[0]);
... put all parameters ...
return linkFactory.constructLink(this, post, params, false); //the last false means not to add jsessionid, true
means add if appropriate
}
}
Then you can use in template:
<a href="" jwcid="pdfReport">Get the report</a>
and in page specification:
<component id="pdfReport" type="serviceLink">
<binding name="service" value="literal:pdf_report"/>
<binding name="parameters" value="{'...'}"/> <!-- create the parameters for service -->
</component>
I hope i didn't miss anythink ...
Jirka
To add the service into application add to your hivemind.xml (If you have none create it in META-INF directory):
<module id="your.package" version="1.0.0">
<service-point id="PdfReport" interface="org.apache.tapestry.engine.IEngineService">
<invoke-factory>
<construct class="instance:your.package.PdfReportService"/>
</invoke-factory>
</service-point>
<contribution configuration-id="tapestry.services.ApplicationServices">
<service name="pdf_report" object="service:your.package.PdfReportService"/>
</configuration>
</module>
Ender Shorty napsal(a):
> Hello all,
>
> I've searched around the forums attempting to discover a way to output a
> file to the user. What I'm trying to do is after creating a pdf file with
> JasperReports i'd like to output it to the user. I use Tapestry 4.02. It
> looks like the old way was to do something like this...
>
> Make a method like the following a a listener, such as from a DirectLink or
> whatever.
>
> (The Document is just a class that holds the file information you want to
> send to the user.)
>
> public void downloadAction(IRequestCycle cycle)
> {
> try
> {
> HttpServletResponse response =
> cycle.getRequestContext().getResponse();
>
>
> byte[] data = new byte[1024];
> FileInputStream in = document.getFileInputstream();
>
>
> response.setHeader("Content-disposition",
> "inline; filename=" +
> document.getFileName());
> response.setContentType(document.getMimeType());
> response.setContentLength(new Long(document.getSize()).intValue());
> ServletOutputStream out = response.getOutputStream();
>
> int bytesRead = 0;
> while ((bytesRead = in.read(data)) > -1)
> {
> out.write(data, 0 , bytesRead);
> }
> in.close();
> response.flushBuffer();
> }
> catch (IOException e)
> {
> e.printStackTrace();
> }
> }
>
> Now it output's a pdf file correctly, and everything seems to work
> fine, but looking at the log, i get serveral of these:
> javax.servlet.ServletException: getOutputStream() has already been
> called for this response
>
> Apparently the new correct way is to create a service. Does anyone
> have an example of outputing a file with a service?
> Thank you very much for any assistance.
>
--
Jiří Mareš (mailto:Jiri.Mares@svt.cz)
ČSAD SVT Praha, s.r.o. (http://www.svt.cz)
Czech Republic
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org