why "session expired" in this solution?

There’s one flaw with the file download solution
HERE

If I push the (button) link once, it works, if I push it twice, it immediately said “Session expired”, no error… why?

Hi,

I find it quite hard to figure out what you’re doing when, and what’s going on - but I’ll venture a guess anyway:
When you do an open for an external url, the browser (some browsers, at least) will think you navigated away from the app, closing the window. Also, one thing that might cause differences in your test vs. main app is if the main app supports multiple windows (overridden application.getWindow()).

Anyway, I just recently tried one solution for downloading while debugging a ticket, you might want to try that: create a hidden iframe (Embedded, browser type) and open the resource there; you should be able to figure out what I’m talking about by looking at the code provided in the ticket:
#9041

(please note that the bug is that the target name contains “-”, so make sure you avoid that if you try this solution)

Best Regards,
Marc

I see no reason why the app session should be expired. The response contains the correct sessionid, so, the application should be alive and accessible

Now I’ve got another problem…

I push the link button, the download pop-up appears, if I choose to open with xml editor, notepad++ or save the file, it saves a project_metrics-n.xml, where n is {1, 2, 3…},
while at the same time it saves project_metrics.xml in the …\Local Settings\Temp dir, but I can only see that because of Firefox Downloads window…

With the popup I get an empty file…

How to set up:
Add the iframe:

		Embedded hiddenIFrameTarget = new Embedded();
		hiddenIFrameTarget.setWidth(0, Sizeable.UNITS_PIXELS);
		hiddenIFrameTarget.setHeight(0, Sizeable.UNITS_PIXELS);
		hiddenIFrameTarget.setType(Embedded.TYPE_BROWSER);
		hiddenIFrameTarget.setSource(new ExternalResource(
				"javascript:false"));
		hiddenIFrameTarget.setDebugId("iframe_target");
		addComponent(hiddenIFrameTarget);

put this in a button’s click listener inside a subwindow ( you can also try adding the iframe on the mainWindow then open it with the mainWindow instead of the subwindow, the result is the same).

ApplicationContext ctx = getApplication().getContext();
				WebApplicationContext webCtx = (WebApplicationContext) ctx;
				ServletContext sc = webCtx.getHttpSession().getServletContext();

				final String path = sc
						.getRealPath("\\WEB-INF\\classes\\download")
						+ "\\project_metrics.xml";

				try {
					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();

//					final FileInputStream is = new FileInputStream(path);

					final File file = new File(fileData.toString());
					final FileResource fileRes = new FileResource(
							new File(path), getApplication()) {

						@Override
						public DownloadStream getStream() {
							try {
								File file = new File(path);
								DownloadStream ds = new DownloadStream(
										new FileInputStream(new File(path)),
										"application/octet-stream",
										"project_metrics.xml");
								ds.setParameter("Content-Length",
										String.valueOf(file.length()));
								ds.setParameter("Content-Disposition",
										"attachment;filename="
												+ "project_metrics.xml");
								ds.setCacheTime(0);
								return ds;
							} catch (final FileNotFoundException e) {
							}
							return null;
						}

					};
					DownloadStream stream = fileRes.getStream();
					stream.setContentType("application/octet-stream");
					stream.setParameter("Content-Disposition",
							"attachment;filename=" + fileRes.getFilename());

					// is = new FileInputStream(path);
					final byte[] bConv = fileData.toString().getBytes();//
					// IOUtils.toByteArray(is);
					final StreamResource.StreamSource source = new StreamResource.StreamSource() {
						public InputStream getStream() {
							return new ByteArrayInputStream(bConv);
						}
					};
					StreamResource sr = new StreamResource(source,
							"project_metrics.xml", getApplication()) {

						@Override
						public DownloadStream getStream() {
							// if (is == null) {
							// return null;
							// }
							DownloadStream ds = new DownloadStream(source.getStream(),
									getMIMEType(), getFilename());
							ds.setBufferSize(getBufferSize());
							ds.setParameter("Content-Length",
									String.valueOf(file.length()));
							ds.setParameter("Content-Disposition",
									"attachment;filename="
											+ "project_metrics.xml");
							ds.setCacheTime(0);
							return ds;
						}

					};
					sr.setMIMEType("application/octet-stream");

					event.getButton().getWindow()
//					getApplication().getMainWindow()
							.open(sr, "PID_Siframe_target"); // fileRes

//					event.getButton().getWindow().requestRepaint();
//					event.getButton().getWindow().requestRepaintAll();
				} catch (IOException e1) {
					e1.printStackTrace();
				}

Ok, I’ve made it work apparently. Trial and error FTW

Change this line:

.open(sr, "PID_Siframe_target"); // fileRes

to this line:

.open(fileRes, "PID_Siframe_target"); // fileRes

Thank you for the i-frame tip