AJAX update and file download in one blowPage edited by christian giambalvoExtended MyPdfResource to be more flexible. Simplified TestPage (no TextField required!)Following example shows how to use an AJAX request to refresh some components and at the same time make the browser ask back for a file to be downloaded. We start with a WebMarkupContainer that is at the same time an IResourceListener import org.apache.wicket.IResourceListener; import org.apache.wicket.markup.html.WebMarkupContainer; /** * @author Ernesto Reinaldo Barreiro ([email protected]) * */ public class DocumentResourceListener extends WebMarkupContainer implements IResourceListener { private static final long serialVersionUID = 1L; private IResourceListener resourceListener; /** * Constructor receiving an IResourceListener.. * * @param id * @param resourceListener */ public DocumentResourceListener(final String id, IResourceListener resourceListener) { super(id); this.resourceListener = resourceListener; } /** * Gets the url to use for this link. * * @return The URL that this link links to */ protected CharSequence getURL() { return urlFor(IResourceListener.INTERFACE); } @Override protected boolean getStatelessHint() { return false; } public void onResourceRequested() { this.resourceListener.onResourceRequested(); } } Next step is to define DynamicWebResource that will serves a PDF file as byte[]. import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.wicket.markup.html.DynamicWebResource; import org.apache.wicket.protocol.http.WebResponse; /** * @author Ernesto Reinaldo Barreiro ([email protected]) * @author Christian Giambalvo ([email protected]) (extended Code) * */ public class MyPdfResource extends DynamicWebResource { private static final long serialVersionUID = 1L; private byte[] content = null; private String attachmentname = null; /** * */ public MyPdfResource() { } /* (non-Javadoc) * @see org.apache.wicket.markup.html.DynamicWebResource#getResourceState() */ @Override protected ResourceState getResourceState() { return new ResourceState() { @Override public String getContentType() { return "application/pdf"; } @Override public byte[] getData() { try { return MyPdfResource.this.content; } catch (Exception e) { return null; } } }; } public String getAttachmentname() { return this.attachmentname; } public void setAttachmentname(final String name) { this.attachmentname = name; } public void setContent(final byte[] content) { this.content = content; } @Override protected void setHeaders(final WebResponse response) { super.setHeaders(response); response.setAttachmentHeader(this.attachmentname); } } One important bit here is the line response.setAttachmentHeader(this.attachmentname);. Otherwise current page will be replaced instead of browser a "Do you want to download file" window. Then we have the page where the "trick" is performed: import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.AbstractReadOnlyModel; /** * @author Ernesto Reinaldo Barreiro ([email protected]) * @author Christian Giambalvo ([email protected]) (extended Code) */ public class TestPage extends WebPage{ private DocumentResourceListener documentResourceListener; private final MyPdfResource pdf; /** * */ public TestPage() { AjaxLink<Void> link = new AjaxLink<Void>("link") { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { if(target!= null) { target.addComponent(this); String pdfFile = "ThePdfFile.pdf"; pdf.setAttachmentname(pdfFile); // pdf2byteArray is a helper method and converts a pdf into a byte array pdf.setContent(pdf2byteArray(pdfFile)); String url = "" target.appendJavascript(";window.location.href='';"); } } }; this.add(link); this.documentResourceListener = new DocumentResourceListener("listener", this.pdf); this.add(documentResourceListener); } } The trick is just the lines: @Override public void onClick(AjaxRequestTarget target) { if(target!= null) { target.addComponent(this); String pdfFile = "ThePdfFile.pdf"; pdf.setAttachmentname(pdfFile); // pdf2byteArray is a helper method and converts a pdf into a byte array pdf.setContent(pdf2byteArray(pdfFile)); String url = "" target.appendJavascript(";window.location.href='';"); } } This will make the browser send back a request to documentResourceListener component who will then stream And for sake of completeness the HTML of the TestPage page: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns:wicket="org.apache.wicket"> <head> </head> <body> <a wicket:id="link">Click Me</a> <div wicket:id="listener"></div> </body> </html> Note: I have tested this with FF-3.5, IE-7 and Chrome. I hope it works fine with other browsers, browser-versions, as well!
Change Notification Preferences
View Online
|
View Change
|
Add Comment
|
- [CONF] Apache Wicket > AJAX update and file download in one ... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
- [CONF] Apache Wicket > AJAX update and file download in... confluence
