Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

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:

Code Block
	final AJAXDownload download = new AJAXDownload()
	{
		@Override
		protected IResourceStream getResourceStream()
		{
			return createResourceStream(item.getModelObject());
		}
	};
	item.add(download);

	item.add(new AjaxLink<Void>("link") {
		@Override
		public void onClick(AjaxRequestTarget target)
		{
			// do whatever with the target, e.g. refresh components
			target.add(...);

			// finally initiate the download
			download.initiate(target);
		}
	});

We have to add a custom behavior which enables us to initiate the download after the AJAX request has been completed. The overridden hook method provides an IResourceStream (e.g. a FileResourceStream) to serve the actual content.

Code Block
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.util.resource.IResourceStream;

/**
 * @author Sven Meier
 * @author Ernesto Reinaldo Barreiro (reiern70@gmail.com)
 * @author Jordi Deu-Pons (jordi@jordeu.net)
 */
public abstract class AJAXDownload extends AbstractAjaxBehavior
{
        private boolean addAntiCache;

        public AJAXDownload() {
    	    this(true);
    	}
    	
	public AJAXDownload(boolean addAntiCache) {
	    super();
	    this.addAntiCache = addAntiCache;
	}

	/**
	 * Call this method to initiate the download.
	 */
	public void initiate(AjaxRequestTarget target)
	{
		String url = getCallbackUrl().toString();

                if (addAntiCache) {
		    url = url + (url.contains("?") ? "&" : "?");
		    url = url + "antiCache=" + System.currentTimeMillis();
		}
 
                // the timeout is needed to let Wicket release the channel
                target.appendJavaScript("setTimeout(\"window.location.href='" + url + "'\", 100);");
	}

	public void onRequest()
	{
		ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(getResourceStream(),getFileName());
		handler.setContentDisposition(ContentDisposition.ATTACHMENT);
		getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
	}

	/**
	 * Override this method for a file name which will let the browser prompt with a save/open dialog.
	 * @see ResourceStreamRequestTarget#getFileName()
	 */
	protected String getFileName()
	{
		return null;
	}

	/**
	 * Hook method providing the actual resource stream.
	 */
	protected abstract IResourceStream getResourceStream();
}