Echo2FileTransferExample es

El siguiente ejemplo muestra cómo construir una sencilla Aplicación-Echo2 que hace uso de la librería Echo2FileTransfer para subir y descargar archivos.


Puedes descargar un archivo .war completo con los fuentes y binarios actuales de la librería Echo2FileTransfer para desplegrala directamente en tu servidor de aplicaciones desde aquí: [WWW] http://swa.zfl.uni-bielefeld.de/~mjablonski/FileTransferDemo.war


Primero necesitamos un sencillo WEB-INF/web.xml para comenzar. Simplemente lo de siempre, nada nuevo que ver.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

    <display-name>FileTransferDemo</display-name>
    
    <servlet>
      <servlet-name>FileTransferDemo</servlet-name>
      <servlet-class>FileTransferDemoServlet</servlet-class>
    </servlet>

    <servlet-mapping>
      <servlet-name>FileTransferDemo</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
        
</web-app>

Eso fue facil... después debemos crear el servlet de aplicación por defecto. Simplemente creamos un archivo Java en el package (paquete) por defecto como FileTransferDemoServlet.java.

import nextapp.echo2.app.ApplicationInstance;
import nextapp.echo2.webcontainer.WebContainerServlet;

public class FileTransferDemoServlet extends WebContainerServlet {        
    public ApplicationInstance newApplicationInstance() {
        return new FileTransferDemo();
    }
}

Y ahora podemos construir la aplicación principal. Para mantener las cosas sencillas, todo el código necesario se ha incluido en el archivo de abajo. En una aplicación real separaríamos las responsabilidades con más cuidado, pero es bueno mantener las cosas sencilla para propósitos educativos.

Además de un pequeño init() que simplemente crea una columna para contener los componentes, hay tres partes interesantes:

Tendrás que modificar esta implementación según tus necesidades. Este ejemplo debería proporcionar la información necesaria generalmente para comprender cómo manejar el contenido.

subida de un fichero.

cuando es pulsado. Tendrás que configurar, activar y encolar un DownloadProvider que proporciona el contenido, tamaño , etc adecuados.

Por favor revisa los comentarios de abajo para hacer las cosas correctamente.

Crea un archivo Java en el package por defecto como FileTransferDemo.java.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.TooManyListenersException;

import nextapp.echo2.app.ApplicationInstance;
import nextapp.echo2.app.Button;
import nextapp.echo2.app.Column;
import nextapp.echo2.app.ContentPane;
import nextapp.echo2.app.Window;
import nextapp.echo2.app.event.ActionEvent;
import nextapp.echo2.app.event.ActionListener;
import nextapp.echo2.app.filetransfer.Download;
import nextapp.echo2.app.filetransfer.DownloadProvider;
import nextapp.echo2.app.filetransfer.UploadEvent;
import nextapp.echo2.app.filetransfer.UploadListener;
import nextapp.echo2.app.filetransfer.UploadSelect;

/**
 * Demo sencilla que muestra cómo transferir archivos con Echo2.
 * 
 * Esta demo permite a todos los usuarios la subida de archivos al directorio temporal
 * del sistema y descargar de nuevo estos archivos en la sesión.
 * 
 * Se trata de un simple ejemplo de utilización de la librería FileTransfer de Echo2.
 * ¡En ningún caso está recomendada para producción!
 * 
 * Por favor tome la preauciones necesarias para asegurar su aplicación cuando
 * permita a los usuarios la subida de contenido a su servidor.
 * 
 * @author Maik Jablonski
 */
public class FileTransferDemo extends ApplicationInstance {

    /**
     * Crea una columna con un selección de subida.
     */
    public Window init() {
        Column column = new Column();
        column.add(getUploadSelect());

        ContentPane contentPane = new ContentPane();
        contentPane.add(column);

        Window window = new Window();
        window.setContent(contentPane);

        return window;
    }

    /**
     * Proporciona una selección de subida y crea crea un botón de descarga
     * para cada cada archivo subido.
     */
    private UploadSelect getUploadSelect() {
        UploadSelect uploadSelect = new UploadSelect();
        try {
            uploadSelect.addUploadListener(new UploadListener() {
                public void fileUpload(UploadEvent uploadEvent) {
                    try {
                        // Leer el contenido del archivo subido.
                        byte[] b = new byte[uploadEvent.getSize()];
                        uploadEvent.getInputStream().read(b, 0,
                                uploadEvent.getSize());

                        // Salvar el contenido a disco usando un FileWrapper.
                        FileWrapper file = new FileWrapper();
                        file.setName(uploadEvent.getFileName());
                        file.setType(uploadEvent.getContentType());
                        file.setContent(b);

                        // Añadir un botón de descarta para el archivo subido
                        ((UploadSelect) uploadEvent.getSource()).getParent()
                                .add(getDownloadButton(file));
                    } catch (IOException ioe) {
                        // Urgs... hacer algo para informar al usuario.
                        ioe.printStackTrace();
                    }
                }

                public void invalidFileUpload(UploadEvent uploadEvent) {
                    // Limpiar si algo fue mal...
                }
            });
        } catch (TooManyListenersException e) {
            // No registrar más de un observador...
        }
        return uploadSelect;
    }

    /**
     * Proporciona un sencillo botón de descarga para un FileWrapper dado.
     * 
     * El botón de descarga tiene un ActionListener, que maneja la descarga de
     * un archivo cuando se pulsa. Por tanto se debe crear, activar y
     * encolar como comando a la aplicación un DownloadProvider.
     */
    private Button getDownloadButton(final FileWrapper file) {
        Button button = new Button(file.toString());
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Download download = new Download();
                download.setProvider(new DownloadProvider() {
                    public String getContentType() {
                        return file.getType();
                    }

                    public String getFileName() {
                        return file.getName();
                    }

                    public int getSize() {
                        return (int) file.getSize();
                    }

                    public void writeFile(OutputStream stream)
                            throws IOException {
                        stream.write(file.getContent());
                    }
                });
                download.setActive(true);
                enqueueCommand(download);
            }
        });
        return button;
    }
}

/*
 * FileWrapper que almacena el contenido en un archivo temporal.
 * 
 * Esto es solo un ejemplo y debería reemplazarse por tu propia implementación
 * dependiendo de tu almacenamiento real.
 */
class FileWrapper {

    private String name;

    private String type;

    private String path;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    /**
     * Obtiene contenido desde un archivo temporal
     */
    public byte[] getContent() throws IOException {
        File file = new File(path);
        byte[] content = new byte[(int) file.length()];
        FileInputStream inputStream = new FileInputStream(file);
        inputStream.read(content);
        inputStream.close();
        return content;
    }

    /**
     * Almacena contenido en un archivo temporal.
     * 
     * Se utilizan los milisegundos actuales como prefijo "semi-único"
     * para el archivo temporal.  Esto generalmente funciona bien
     * para propósitos demostrativos sin demasiada concurrencia.
     * Por favor, utlice una secuencia "real" única synchronized
     * (sincronizada) para usos en producción.
     */
    public void setContent(byte[] content) throws IOException {
        File tmpFile = File.createTempFile(String.valueOf(System
                .currentTimeMillis()), null);
        // Ejecuta correctamente y borra archivos cuando la aplicación se denga...
        tmpFile.deleteOnExit();        
        path = tmpFile.getCanonicalPath();
        FileOutputStream outputStream = new FileOutputStream(tmpFile);
        outputStream.write(content);
        outputStream.close();
    }

    public long getSize() {
        return new File(path).length();
    }

    public String toString() {
        return name + " (" + type + ")" + " [" + getSize() / 1024 + " KB]"; 
    }
}

Ahora puedes arrancar tu contenedor y visitar la página usando http://localhost:8080/.


English Version

last edited 2007-03-08 08:59:02 by rubensa