This Confluence has been LDAP enabled, if you are an ASF Committer, please use your LDAP Credentials to login. Any problems file an INFRA jira ticket please.

Child pages
  • AJAX update and file download in one blow
Skip to end of metadata
Go to start of metadata

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:

	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.

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();
}
  • No labels

2 Comments

  1. @ Ernesto Reinaldo Barreiro

    What is the license that you would want to put this tool under?

    Best Regards,

    Wei

    1. I'm not the only contributor. Original idea/version was mine but Sven and Martin, and others, have improved on it. For me same licence as Wicket would be fine.

      Best Regards,

      Ernesto