Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Remote Application Platform (RAP) » How to open/download a file?
How to open/download a file? [message #1059826] Tue, 21 May 2013 14:27 Go to next message
Julia Kurde is currently offline Julia Kurde
Messages: 61
Registered: November 2011
Location: Berlin, Germany
Member
Hello,
How can I open a file, e.g. a pdf, that is located in one plugin of the application?

I already have

ServiceManager manager = RWT.getServiceManager();
String urlString = URLHelper.getContextURLString();
urlString = urlString + manager.getServiceHandlerUrl(DownloadServiceHandler.ID);
System.out.println(urlString); // http://127.0.0.1:8080/jlzhview?servicehandler=download

IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench().getBrowserSupport();
try {
  IWebBrowser browser = browserSupport.createBrowser(
    IWorkbenchBrowserSupport.AS_EDITOR, "id", "name", "tooltip");

  urlString = urlString + "&filename=" + "theFile.pdf";
  browser.openURL(new URL(urlString));

} catch (PartInitException | MalformedURLException e) {
  //some Exception handling...	
}


The DownloadServiceHandler is registered when the application starts and it is pretty simple:
public class DownloadServiceHandler implements ServiceHandler {
	
  public static final String ID = "download";

  public void service(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {

    String fileName = request.getParameter( "filename" );
    String contentDisposition = "attachment; filename=\"" + fileName + "\"";
    response.setHeader( "Content-Disposition", contentDisposition );
  }
}

This will open a new Browser window with a message box asking if the file should be opened or saved. But that cannot work because the file path is missing (the file cannot be found)!
So how to define the path to the file in the URL? In the RCP I would get it like this:
URL root = MyPlugin.getDefault().getBundle().getEntry("/");
URL url = new URL(root, "/documentation/theFile.pdf");
url = FileLocator.resolve(url);

This is the absolute path of that file. But in RAP I need it relative to the servlet path, which I get from manager.getServiceHandlerUrl(String) and it will need some "&path=..." or something like that in the URL (I guess).

Or do I have to store files that can be downloaded in a special download folder on the server?

Thanks for your help!
Regards,
Julia
Re: How to open/download a file? [message #1059881 is a reply to message #1059826] Wed, 22 May 2013 01:42 Go to previous messageGo to next message
Yury Mising name is currently offline Yury Mising name
Messages: 91
Registered: May 2010
Location: Russia
Member
Hello, Julia!

Julia Kurde wrote on Wed, 22 May 2013 00:27
Hello,
Or do I have to store files that can be downloaded in a special download folder on the server?


Yes, you have to. And write this file to response in DownloadServiceHandler:

FileInputStream stream = new FileInputStream(path_to_file);
OutputStream os = response.getOutputStream();
/*copy stream to os */


Best regards,
Yury.
Re: How to open/download a file? [message #1059915 is a reply to message #1059881] Wed, 22 May 2013 03:32 Go to previous messageGo to next message
Ralf Sternberg is currently offline Ralf Sternberg
Messages: 1290
Registered: July 2009
Senior Member

right, you have to copy the bits from an input stream to the response's
output stream. You don't have to store your files on disk, you just need
an input stream to read their contents from. I think you get this input
stream from the URL, or you can use getResourceAsStream() from the
bundle's classloader.

Ralf

--
Ralf Sternberg

Twitter: @EclipseRAP
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: How to open/download a file? [message #1059919 is a reply to message #1059915] Wed, 22 May 2013 03:59 Go to previous messageGo to next message
Phill Perryman is currently offline Phill Perryman
Messages: 214
Registered: July 2009
Senior Member
Try something like the following. The plugin (myplugin.rwt) contains a folder (files) with the resource (test.pdf). This is the sendResponse method of the service handler. I also put it into an array first so the response stream in uncontaminated if an error arises (not shown here) so I can then output an html doc with an error explanation. It uses try (resource) from java 7 so if not using then you will need some finally (close stream) stuff.

public void sendResponse(HttpServletRequest request, HttpServletResponse response) throws Exception {
int i;
URL url = new URL("platform:/plugin/swb3.rwt/files/test.pdf");
response.setContentType("application/pdf");
response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
response.setHeader("Cache-Control", "max-age=0");
try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream inputStream = url.openConnection().getInputStream()) {
while ((i = inputStream.read()) != -1)
baos.write(i);
final byte[] byteArray = baos.toByteArray();
response.setContentLength(byteArray.length);
try (ServletOutputStream outputStream = response.getOutputStream()) {
outputStream.write(byteArray);
}
}
}
Re: How to open/download a file? [message #1059981 is a reply to message #1059919] Wed, 22 May 2013 08:39 Go to previous messageGo to next message
Julia Kurde is currently offline Julia Kurde
Messages: 61
Registered: November 2011
Location: Berlin, Germany
Member
Thanks for your answers! I was a bit confused how to pass parameters to the ServiceHandler. Finally I did it like this:
public class PdfServiceHandler implements ServiceHandler {
 
 public static final String ID = "pdf_download";
 
 private static final String P1 = "p1";
 private static final String P1 = "p2";
 private static final String P3 = "p3";
 
 public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
  String p1String = request.getParameter(p1);
  String p2String = request.getParameter(p2);
  String p3String = request.getParameter(p3);
  
  URL url = new URL(/* generate file URL using p1, p2, p3 */);
  
  /* give some information about the file */
  response.setContentType("application/pdf");
  String contentDisposition = "attachment; filename=\"" + p1 + "\"";
  response.setHeader("Content-Disposition", contentDisposition);

  /* write the file content */
  int i;
  try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    InputStream inputStream = url.openConnection().getInputStream()) {
   while ((i = inputStream.read()) != -1) {
    baos.write(i);
   }
   final byte[] byteArray = baos.toByteArray();
   response.setContentLength(byteArray.length);
   try (ServletOutputStream outputStream = response.getOutputStream()) {
    outputStream.write(byteArray);
   }
  }
 }
 
 /* generate the URL that is passed to the browser using some parameters */
 public static String generateUrlString(String p1String, String p2String, String p3String) {
  String urlString = URLHelper.getContextURLString();
  urlString = urlString + RWT.getServiceManager().getServiceHandlerUrl(ID);
  urlString = urlString +
    "&" + P1 + "=" + p1String+
    "&" + P2 + "=" + p2String+
    "&" + P3 + "=" + p3String;
  return urlString;
 }
 
}

And in the action that is related to the download button:
IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench().getBrowserSupport();
IWebBrowser browser = browserSupport.createBrowser(
  IWorkbenchBrowserSupport.AS_EDITOR, "id", "name", "tooltip");
/* the actual values for the params are generated in the action */
String urlString = PdfServiceHandler.generateUrlString("param1", "param2", "param3");

browser.openURL(new URL(urlString));

This works fine so far! What I don't like so much is that the browser will open as a popup. Is it possible to change that behavior? Actually it would be best, if the pdf is opened directly in a new browser tab.

Thanks again!

Regards,
Julia
Re: How to open/download a file? [message #1059988 is a reply to message #1059981] Wed, 22 May 2013 09:05 Go to previous messageGo to next message
Phill Perryman is currently offline Phill Perryman
Messages: 214
Registered: July 2009
Senior Member
I think that is because you have it as an attachment. Try

response.setContentType("application/pdf");
response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
response.setHeader("Cache-Control", "max-age=0");

no content disposition, certainly in IE that just pops open a new tab, have not tried the other browsers. May depend on the tab handling of the browser as well.

Re: How to open/download a file? [message #1059993 is a reply to message #1059988] Wed, 22 May 2013 09:20 Go to previous messageGo to next message
Phill Perryman is currently offline Phill Perryman
Messages: 214
Registered: July 2009
Senior Member
If you don't want to use the parameter you can always use the httpSession as this allows you to store Objects

HttpSession httpSession = RWT.getUISession().getHttpSession();
httpSession.setAttribute(name, objectToSave);
and to retrieve
Object objectToSave=httpSession.getAttribute(name);
Re: How to open/download a file? [message #1060021 is a reply to message #1059993] Wed, 22 May 2013 10:47 Go to previous messageGo to next message
Julia Kurde is currently offline Julia Kurde
Messages: 61
Registered: November 2011
Location: Berlin, Germany
Member
Right, when I take out "attachment" from the "Content-Disposition", or don't set it at all, the file is opened directly, but still in a popup window. I tried IE 10, Chrome, Nightly (that's a 64 bit firefox) and the Eclipse internal browser (this one will need at least the file name).

And I don't see any effect when setting or not setting
response.setContentType("application/pdf");
response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
response.setHeader("Cache-Control", "max-age=0");

The content type seems to be determined by the file content automatically (except Eclipse internal browser). Maybe that's different for older/other browsers. So setting it doesn't hurt.

What exactly means "Cache-Control"? The file will not change, so if it was downloaded once, it can be read from the cache without any problem.
So if I don't set "Cache-Control", the file will be cached?
Re: How to open/download a file? [message #1060066 is a reply to message #1060021] Wed, 22 May 2013 15:43 Go to previous messageGo to next message
Markus  rüger is currently offline Markus rüger
Messages: 364
Registered: July 2009
Senior Member
Julia Kurde <forums-noreply@xxxxxxxx> wrote:
> Right, when I take out "attachment" from the "Content-Disposition", or
> don't set it at all, the file is opened directly, but still in a popup
> window. I tried IE 10, Chrome, Nightly (that's a 64 bit firefox) and the
> Eclipse internal browser (this one will need at least the file name).
> And I don't see any effect when setting or not setting
>
> response.setContentType("application/pdf");
> response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
> response.setHeader("Cache-Control", "max-age=0");
>
> The content type seems to be determined by the file content automatically
> (except Eclipse internal browser). Maybe that's different for older/other
> browsers. So setting it doesn't hurt.
> What exactly means "Cache-Control"? The file will not change, so if it
> was downloaded once, it can be read from the cache without any problem.
> So if I don't set "Cache-Control", the file will be cached?

Hi Julia

the browser decides how to open popups. You can change this in the settings
of your browser.
And if I remember correctly there is no way in changing this behavior.

Regards
Markus
Re: How to open/download a file? [message #1060104 is a reply to message #1060066] Thu, 23 May 2013 03:01 Go to previous messageGo to next message
Phill Perryman is currently offline Phill Perryman
Messages: 214
Registered: July 2009
Senior Member
Sorry the no-cache was from my code as I generate the PDF documents on the fly, I just changed it a bit t use a static file for this example. As yours are static you don't need it.
Re: How to open/download a file? [message #1060139 is a reply to message #1060104] Thu, 23 May 2013 05:38 Go to previous message
Julia Kurde is currently offline Julia Kurde
Messages: 61
Registered: November 2011
Location: Berlin, Germany
Member
OK, thanks a lot!

Processing the inputStream in the ServiceHandler even works for files coming via ftp from another server if I use an org.apache.commons.net.ftp.FTPClient instead of just url.openConnection().getInputStream().

That's really great!

regards,
Julia
Previous Topic:Infocenter as a WAR
Next Topic:How to get install folder of the application?
Goto Forum:
  


Current Time: Thu Jul 31 07:32:22 EDT 2014

Powered by FUDForum. Page generated in 0.05781 seconds