Apache Wicket - stahování z aplikace

Květen 15, 2008 – 10:45 am

Dalo to chvilku zabrat, ale první blog post je na světě. Dnes to bude o stahování souborů pomocí Apache Wicket. Rozeberu tu 3 možnosti jak na to.


Pomocí Linku

Wicket poskytuje již hotovou třídu wicket.markup.html.link.DownloadLink. Jako parametr se jí pošle java.io.File a o zbytek se postará Wicket.

Java:

// stahovani pomoci linku
form.add(new DownloadLink("downloadLink", createExampleFile()));

HTML:

<a href="#" wicket:id="downloadLink">Stažení souboru</a>

Pomocí Buttonu

V metodě onSubmit tlačítka připravíme soubor pro stažení, vytvoříme ResourceStream pro tento soubor a dále upravíme RequestTarget v RequestCycle tak, aby ukazovala na naší ResourceStream.

Java:


// stahovani pomoci Buttonu
Button downloadButton = new Button("downloadButton"){

    @Override
    public void onSubmit() {
        File downloadFile = createExampleFile();
        FileResourceStream fileStream = new
                    FileResourceStream(downloadFile); 

        getRequestCycle().setRequestTarget(
                    new ResourceStreamRequestTarget(fileStream));
    }
};

form.add(downloadButton);

HTML:


<input type="submit" wicket:id="downloadButton" value="Stažení souboru" />

Pomocí AjaxButtonu

V metodě onSubmit tlačítka připravíme soubor pro stažení, načteme ho do bufferu pomocí InputStream. Vytvoříme DynamicWebResource, která je wrapper okolo našeho souboru (obsahuje informace o názvu souboru, content typu a datech souboru). Tuto DynamicWebResource musíme zaregistrovat do SharedResources a získat odkaz na ní (WicketUtils je knihovní třída - její kód je zobrazen níže). Poslední krok je do RequestTargetu přidat Javascript, který nám otevře nové okno, s odkazem na naší DynamicWebResource. Tím se provede stažení a nově otevřené okno zmizí.

Java:


// stahovani pomoci AjaxButtonu
AjaxButton downloadAjaxButton = new AjaxButton("downloadAjaxButton") {

    @Override
    protected void onSubmit(AjaxRequestTarget target, Form form) {
        try{
            File downloadFile = createExampleFile();
            FileInputStream input = new
            FileInputStream(downloadFile);

            final byte[] buffer = new byte[1024];
            input.read(buffer);

            DynamicWebResource resource = new
                DynamicWebResource("exampleFile.txt") {

                @Override
                protected ResourceState getResourceState() {
                    return new ResourceState() {

                        @Override
                        public String getContentType() {
                            return "text/plain";
                        }

                        @Override
                        public byte[] getData() {
                            return buffer;
                        }
                    };
                }
            };

            String url = WicketUtils.getUrlForResource(
                                            getApplication(),
                                            getRequestCycle(),
                                            resource);

            // pridani JavaScriptu do AJAX response, ktery otevre
            // popup okno s downloadem
            target.appendJavascript("window.open(\"" +
                                    url + "\", \"stahovani\"," +
                                    "\"width=100,height=100\");");
        } catch(Exception e){
            throw new RuntimeException(e);
        }
    }
};

form.add(downloadAjaxButton);

HTML:

<input type="submit" wicket:id="downloadAjaxButton" value="Stažení souboru (AJAX)" />

WicketUtils.java


package cz.tigra.examples.downloads.utils;

import org.apache.wicket.Application;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Resource;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.SharedResources;

public class WicketUtils {

    private static final String RESOURCE_NAME = "download";

    /**
     *
     * Pomocna metoda. Vraci url pro Resource
     *
     * @param app pouziva se jako scope a k ziskani objektu SharedResources
     * @param reqCycle k ziskani url
     * @param targetResource dany zdroj ktery bude ResourceReference vracet
     * @return url pro danou reference
     */
    public static String getUrlForResource(
              final Application app,
              final RequestCycle reqCycle,
              final Resource targetResource) {

        SharedResources sharedRes = app.getSharedResources();

        String resKey = sharedRes.resourceKey(app.getClass(),
                                        RESOURCE_NAME, null, null);
        sharedRes.remove(resKey);

        ResourceReference fileReference =
                    new ResourceReference(app.getClass(), RESOURCE_NAME) {
            @Override
            protected Resource newResource() {
                return targetResource;
            }
        };

        return reqCycle.urlFor(fileReference).toString();
    }
}

Doufám, že vám to ušetří pár chvil s Googlem.

Vlastimil Dolejš