Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
file download problem in main app when in test app works - widgetset?
I've got my main app, in which the same code from test app for download file fails to work with URL:
http://localhost/rl/APP/2/project_metrics.xml
and showing in browser client area:
http://localhost/rl/APP/2/project_metrics.xml
I've attached the test code that works (in two ways), from main window and subwindow, that if I paste in main app doesn't work (from subwindow)
I've also attached two images of the traffic it generates. Main app calls on the subwindow but immediately replaces it with a GET request that shows the above described behaviour. The test app shows two requests and return the file properly.
Have no ideea why main app does a 302 redirect with this. I've had a domain name set in hosts file set up for 127.0.0.1 and that's it (I removed it, also need to restart or something?). Also my router is set up to forward requests to that computer (but their incoming), not originating from the same computer, as I'm working on it...
One noticeable difference I can think of is that main application widgetset is built differently, to load resources dynamically... but I doubt that's it
Anyone has any ideea what could be the problem please?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
<module>
<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
<generate-with class="view.MyWidgetMapGenerator">
<when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" />
</generate-with>
<inherits name="org.vaadin.vaadinvisualizations.widgetset.VaadinvisualizationApplicationWidgetset" />
<inherits name="com.vaadin.addon.timeline.gwt.TimelineWidgetSet" />
</module>
Changed
getApplication().getMainWindow().open(sr);
to
event.getButton().getWindow().open(sr);
and now the result in the main app is that the download starts, but the content of the subwindow is wiped out.
the traffic not consists of two requests as in the test app, the first regular request, as in the test app, but the GET request that shouldn't be there comes immediately after
I need to stop making this GET request... or make it not affect the window conten... how? What does the window content have to do with it anyway? It has been set as attachment...
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: max-age=86400
Expires: Mon, 09 Jul 2012 20:44:58 GMT
Pragma: cache
Content-Disposition: filename="project_metrics.xml"
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Date: Sun, 08 Jul 2012 20:44:58 GMTRequest Headersview source
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Connection keep-alive
Cookie JSESSIONID=EEE5583FFD47736A5C57D7BC686E73C2
Host localhost
Referer http://localhost/rl
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1
Some variation of the code I picked up from a bug fix that produces the same result as above:
class DownloadResource extends StreamResource {
private final String filename;
public DownloadResource(StreamSource streamSource, String name,
Application application) {
super(streamSource, name, application);
filename = name;
}
@Override
public DownloadStream getStream() {
DownloadStream stream = new DownloadStream(getStreamSource()
.getStream(), "text/plain", filename);
stream.setParameter("Content-Disposition", "attachment;filename="
+ filename);
return stream;
}
}
...
try {
ApplicationContext ctx = getApplication().getContext();
WebApplicationContext webCtx = (WebApplicationContext) ctx;
ServletContext sc = webCtx.getHttpSession()
.getServletContext();
String path = sc.getRealPath("\\WEB-INF\\classes")
+ "\\project_metrics.xml";
StringBuffer fileData = new StringBuffer(1000);
BufferedReader reader = new BufferedReader(new FileReader(
path));
char[] buf = new char[1024];
int numRead = 0;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
Window w = event.getButton().getWindow();
final String data = fileData.toString();
StreamSource streamSource = new StreamSource() {
public InputStream getStream() {
return new ByteArrayInputStream(data.getBytes());
}
};
w.open(new DownloadResource(streamSource,
"project_metrics.xml", event.getButton()
.getApplication()));
} catch (IOException e1) {
e1.printStackTrace();
}
Oh cmon... why are the simplest things so complicated here... do I really have to use another servlet to download files?
Solution and end of story (I hope)
1.
String filename = "project_metrics.xml";
getApplication().getMainWindow().open(new ExternalResource(getApplication().getURL() + "//download?filename=" + filename));
2.
<servlet>
<servlet-name>DownloadServlet
</servlet-name>
<servlet-class>init.DownloadServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
3.
package init;
import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String filename = req.getParameter("filename");
String path = req.getSession().getServletContext()
.getRealPath("\\WEB-INF\\classes\\download" + "\\" + filename);
// TODO: assess optimal buffer size by the average length of files
// perhaps
// get file data in memory
StringBuffer fileData = new StringBuffer(4096);
BufferedReader reader = new BufferedReader(new FileReader(path));
char[] buf = new char[4096];
int numRead = 0;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[4096]; // TODO: needed?
}
// set header
PrintWriter out = resp.getWriter();
resp.setContentType("application/octet-stream");
resp.setContentLength(fileData.length());
resp.setHeader("Content-Disposition", "attachment;filename=" + filename);
// write file data to output stream
Reader inFileStream = null;
try {
inFileStream = new CharArrayReader(fileData.toString()
.toCharArray());
char[] outputChars = new char[fileData.length()];
out.flush();
while (inFileStream.read(outputChars, 0, fileData.length()) != -1) {
out.write(outputChars, 0, fileData.length());
}
} finally {
inFileStream.close();
}
}
}