Download File

Hi,

i have a problem with downloading a File.
I get the File with FileResource and set the resource on a links.
This works fine.
But now i want to download the file when i click on a button. (Window with open / save like Firefox ) :bashful:
Could anyone help me with this Problem?

Thanks,
hohausfn

In your button’s click listener , use open(…) method of your main or dialog Window class:

Window myWindow = ... // get an instance of your window
myWindow.open ( myResource );

Thanks it works.

But now a file like name.pdf opens automatically in the Browser.
I want that the user could choose open / save as.

I tried this but it doesn’t work:

fileResource.getStream().setParameter(“Content-Disposition”, “attachment; filename=” + file.getName());

thanks,
hohausfn

I looked how streamresources are served and it seems to create NEW downloadstream everytime getStream() is invoked so that call doesn’t do anything because ApplicationServlet gets another downloadstream that doesn’t have Content-Dispotion set.

You can use handleURI in Application to make that content-dispostion work. Example if you override handleURI like this:

@Override
	public DownloadStream handleURI(URL context, String relativeUri) {
		if (relativeUri.equals("test.txt")) {
			DownloadStream ds = new DownloadStream(new ByteArrayInputStream("test".getBytes()), "text/plain", "test.txt");
			ds.setParameter("Content-Disposition", "attachment; filename=test.txt");
			return ds;
		} else {
			return super.handleURI(context, relativeUri);
		}
	}

You can open that uri using External resource:

@Override
			public void buttonClick(ClickEvent event) {
				WebApplicationContext ctx = (WebApplicationContext) getContext();
				String path = ctx.getHttpSession().getServletContext().getContextPath();
				event.getButton().getWindow().open(new ExternalResource(path + "/test.txt"));
			}

Another option would be to extend FileResource and create something like a FileDownloadResource. The only method that should need overriding is

    public DownloadStream getStream() {
        try {
            final DownloadStream ds = new DownloadStream(new FileInputStream(
                    sourceFile), getMIMEType(), getFilename());
            ds.setCacheTime(cacheTime);
            return ds;
        } catch (final FileNotFoundException e) {
            // No logging for non-existing files at this level.
            return null;
        }
    }

Adding the Content-Disposition here could be cleaner than making a custom uri handler.

I like your solution. Here is what I tried: It didn’t work for me. It still open the file in the browser directly instead of prompting to save… What did I miss?

class FileDownloadResource extends FileResource{

public FileDownloadResource(File sourceFile, Application application) {
	super(sourceFile, application);
}
public DownloadStream getStream() {
    try {
        final DownloadStream ds = new DownloadStream(new FileInputStream(
        		getSourceFile()), getMIMEType(), getFilename());
        ds.setParameter("Content-Disposition", "attachment; filename="+getFilename());
        ds.setCacheTime(getCacheTime());
        return ds;
    } catch (final FileNotFoundException e) {
        // No logging for non-existing files at this level.
        return null;
    }
}

}

then, on the button click:
public void buttonClick(ClickEvent event) {
String path = getApplication().getContext().getBaseDirectory().getAbsolutePath();
event.getButton().getWindow().open(new FileDownloadResource(
new File(path+File.separatorChar+“VAADIN”+File.separatorChar+“export”+
File.separatorChar+document.getName()+“.xml”), docPanel.getApplication()));
}
});

Hmm… this seems correct, but make sure the getFilename() returns name of the file without the path.

Also, you may want to test with different browsers. Some (older browsers) may require an unknown MIME type to force the download dialog.

I got in the same problem and was curious if you have already found a solution. I want to show a saveFile dialog instead of showing the content in a new window.

Thanks!!

No. I am still living with this behavior… BTW, I am developing with Chrome.

Hi,

I created the same FileDownloadResource class with overridden getStream() method. Everything works fine, but when I try to download file with filename which has different encoding (UTF-8), I get corrupted filename even if I set encoding to UTF-8 in content-type header. I tried to encode file name with java.net.URLEncoder & it worked but not for all symbols, besides it changed spaces to “+” signs. Could you please advise is there any possibility to encode filename to UTF-8 without any filename modifications.

Thanks,
Alexander

I need to do something similar. Were you able to get it working? If so, could you explain a bit more about what it you did. In particular, I don’t understand this part:

new File(path+File.separatorChar+“VAADIN”+File.separatorChar+“export”+
File.separatorChar+document.getName()+“.xml”), docPanel.getApplication())

Thanks,

Matthew Fleming

to download instead of opening it in the browser just use that a little different string


ds.setParameter("Content-Disposition", "attachment; filename=\"" +getFilename() + "\"");

Hope it could help
Regards, Igor

Tried this soulution, but it doesn’ work too :frowning:

Vaadin gurus please help to solve this issue!!!

:angry:

Sorry, solution is found :slight_smile:

A colleague once helped with this.
Try to putting “_blank” to force a new window

event.getButton().getWindow().open(_downloader.createResource(), "_blank");

The window.open method seems to get blocked by some browsers as “unsolicited popups,” presumably because the click is not on a link, even though it may be in response a button click. Didn’t try Link instead of Button to see if it would be different.

Also, I noted that if you a “_blank” target on Chrome, it can popup a big window with the “accept/decline of the saving of the file” in the lower left corner, where most will not even notice as the window itself is blank. On FF, it seems to open a nice dialog. And IE seems to interpret the data regardless of the mime type set, so if it’s HTML/XML/TXT/PNG/JPEG/GIF, it may just open it for view without a save option. Safari also seems to do this, often showing XML data in a really ugly way (without a download option).

I wonder if there’s any way to make a download button create an open/save dialog no matter what, perhaps by tweaking for different browser types, or whether it’s a fool’s errand to try to resolve this with all the different browser schemes. I changed “_blank” to “_top” for Chrome to avoid the new, blank browser window, so the Accept/Reject option is on the main browser window, but doing that for other browsers replaces the page.

Where does “document” come from in that example code? How do I specify the server file that I want to download?

Hi,

I created the same FileDownloadResource class with overridden getStream() method. Everything works fine, but when I try to download file with filename which has different encoding (UTF-8), I get corrupted filename even if I set encoding to UTF-8 in content-type header. I tried to encode file name with java.net.URLEncoder & it worked but not for all symbols, besides it changed spaces to “+” signs. Could you please advise is there any possibility to encode filename to UTF-8 without any filename modifications.

Thanks,
Alexander

hi,Alexander
i’v solved same problem with follow code-_-,good luck

final DownloadStream ds = new DownloadStream(new FileInputStream(
getSourceFile()), getMIMEType(), getFilename());
try {
ds.setParameter(“Content-Disposition”, “attachment; filename=”
+
URLEncoder.encode(getFilename(),“utf-8”)
);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ds.setCacheTime(getCacheTime());

        return ds;

I found this thread very useful, it show how to download PDF Instead of opening it.


http://vaadin.com/forum/-/message_boards/view_message/124004

Feng shen home, I have the same issue Alexander had. The file gets downloaded, but doesnt open in proper format. A message saying"The fie is not properly decoded…" appears. I have tried the same thing you gave above. it did not work for me.

Alexander, did you get it to work…