AJAX update and file download in one blowPage edited by Ernesto Reinaldo BarreiroFollowing 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 "test.pdf" PDF file taken from the resources. 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]) * */ public class MyPdfResource extends DynamicWebResource { private static final long serialVersionUID = 1L; static int BUFFER_SIZE = 10*1024; /** * */ 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 bytes(MyPdfResource.class.getResourceAsStream("test.pdf")); } catch (Exception e) { return null; } } }; } public static byte[] bytes(InputStream is) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); copy(is, out); return out.toByteArray(); } @Override protected void setHeaders(WebResponse response) { super.setHeaders(response); response.setAttachmentHeader("test.pdf"); } public static void copy(InputStream is, OutputStream os) throws IOException { byte[] buf = new byte[BUFFER_SIZE]; while (true) { int tam = is.read(buf); if (tam == -1) { return; } os.write(buf, 0, tam); } } } One important bit here is the line response.setAttachmentHeader("test.pdf");. 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]) * */ public class TestPage extends WebPage{ private Label text; private String labelText = "Hi!"; private DocumentResourceListener documentResourceListener; /** * */ public TestPage() { AjaxLink<Void> link = new AjaxLink<Void>("link") { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { TestPage.this.labelText = "Hi! and donwload a file!"; if(target!= null) { target.addComponent(TestPage.this.text); String url = "" target.appendJavascript(";window.location.href='';"); } } }; add(link); text = new Label("text", new AbstractReadOnlyModel<String>() { private static final long serialVersionUID = 1L; @Override public String getObject() { return TestPage.this.labelText; } }); text.setOutputMarkupId(true); add(text); documentResourceListener = new DocumentResourceListener("listener", new MyPdfResource()); add(documentResourceListener); } } The trick is just the lines:
@Override
public void onClick(AjaxRequestTarget target) {
TestPage.this.labelText = "Hi! and donwload a file!";
if(target!= null) {
target.addComponent(TestPage.this.text);
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> <span wicket:id="text"></span> <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
