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>

12435.png
12436.png
12437.java (9.13 KB)

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

[b]

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…
[/b]

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)

String filename = "project_metrics.xml";
getApplication().getMainWindow().open(new ExternalResource(getApplication().getURL() + "//download?filename=" + filename));
<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>
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();
		}
	}

}

Has one flaw, see
HERE