Pour envoyer plusieurs fichiers d’un coups vers un serveur sans passer par un zip, il existe deux solutions évidentes qui sont :

  • L’applet Java
  • Flash

J’ai choisi d’illustrer la seconde solution au travers d’un exemple mettant en œuvre Stripes et SWFUpload
logostripes.pngminnelli_logo.png

J’utilise Eclipse comme IDE. L’objet de ce billet n’est pas d’entrer dans le détail du fonctionnement d’Eclipse, je considère que le lecteur est donc familier de cet outil. J’utilise également le plugin Maven2 pour Eclipse.

Création du pom du projet.

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.fullsix</groupId>
    <artifactId>demo</artifactId>
    <packaging>war</packaging>
    <name />
    <version>0.0.1-SNAPSHOT</version>
    <description />
    <build>
        <finalName>demo</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <configuration>
                    <contextPath>/</contextPath>
                    <connectors>
                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                            <port>8080</port>
                        </connector>
                    </connectors>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.stripes</groupId>
            <artifactId>stripes</artifactId>
            <version>1.4.3</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.4</version>
        </dependency>
    </dependencies>
</project>

Voici le Web.xml :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app id="Communautaire_Front" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>SWF Upload</display-name>

    <filter>
        <display-name>Stripes Filter</display-name>
        <filter-name>StripesFilter</filter-name>
        <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
        <init-param>
            <param-name>ActionResolver.UrlFilters</param-name>
            <param-value>classes</param-value>
        </init-param>
        <init-param>
            <param-name>ActionResolver.PackageFilters</param-name>
            <param-value>com.fullsix.demo.action.*</param-value>
        </init-param>
        <init-param>
            <param-name>MultipartWrapper.Class</param-name>
            <param-value>net.sourceforge.stripes.controller.multipart.CommonsMultipartWrapper</param-value>
        </init-param>
        <init-param>
            <param-name>FileUpload.MaximumPostSize</param-name>
            <param-value>500m</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>StripesFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <filter-mapping>
        <filter-name>StripesFilter</filter-name>
        <servlet-name>StripesDispatcher</servlet-name>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <servlet>
        <servlet-name>StripesDispatcher</servlet-name>
        <servlet-class>net.sourceforge.stripes.controller.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>StripesDispatcher</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

    <!-- The Usual Welcome File List -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

Voici l’action Stripes :

package com.fullsix.demo.action;

import java.io.File;
import java.io.IOException;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.FileBean;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.controller.StripesRequestWrapper;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 *
 * @author Damien Viel 
 * @version $Id$
 *
 */
@UrlBinding(”/upload.action”)
public class UploadActionBean implements ActionBean {

    private static final Log logger = LogFactory.getLog(UploadActionBean.class);
    private ActionBeanContext context;
    private FileBean filedata;

    @SuppressWarnings(”unused”)
    @Before(LifecycleStage.BindingAndValidation)
    private void rehydrate(){
        String filename = getContext().getRequest().getParameter(”Filename”);

        if (StringUtils.isNotEmpty(filename)){
            StripesRequestWrapper req = (StripesRequestWrapper)getContext().getRequest();
            filedata = req.getFileParameterValue(”Filedata”);
        }
    }

    public ActionBeanContext getContext() {
        return this.context;
    }

    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @DefaultHandler
    public Resolution upload() {
        if (filedata!=null){
            try {
                filedata.save(new File(filedata.getFileName()));
            } catch (IOException e) {
                logger.error(”Error while writing file :” + filedata.getFileName());
            }
        }
        return new ForwardResolution(”/success.jsp”);
    }
}

Création de la JSP .

Pour faire simple, j’ai repris le code du “simpleExample” de la demo en ligne de SWFUpload.


<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="stripes"%>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>SWFUpload Demos - Simple Demo</title>
<link href="css/swf.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="swfupload/swfupload.js"></script>
<script type="text/javascript" src="js/swfupload.queue.js"></script>
<script type="text/javascript" src="js/fileprogress.js"></script>
<script type="text/javascript" src="js/handlers.js"></script>
<script type="text/javascript">
		var swfu;

		window.onload = function() {
			var settings = {
				flash_url : "swfupload/swfupload_f9.swf",
				upload_url: "http://localhost:8080/upload.action",	// Relative to the SWF file
				post_params: {"Test" : "coucou"},
				file_size_limit : "100 MB",
				file_types : "*.*",
				file_types_description : "All Files",
				file_upload_limit : 100,
				file_queue_limit : 0,
				custom_settings : {
					progressTarget : "fsUploadProgress",
					cancelButtonId : "btnCancel"
				},
				debug: false,

				// The event handler functions are defined in handlers.js
				file_queued_handler : fileQueued,
				file_queue_error_handler : fileQueueError,
				file_dialog_complete_handler : fileDialogComplete,
				upload_start_handler : uploadStart,
				upload_progress_handler : uploadProgress,
				upload_error_handler : uploadError,
				upload_success_handler : uploadSuccess,
				upload_complete_handler : uploadComplete,
				queue_complete_handler : queueComplete	// Queue plugin event
			};

			swfu = new SWFUpload(settings);
	     };
	</script>
</head>
<body>

<div id="content">
	<h2>Simple Demo</h2>
<stripes:form beanclass="com.fullsix.demo.action.UploadActionBean" id="form1">

	<p>This page demonstrates a simple usage of SWFUpload.  It uses the Queue Plugin to simplify uploading or cancelling all queued files.</p>

			<fieldset class="flash" id="fsUploadProgress">
			<legend>Upload Queue</legend>
			</fieldset>
		<div id="divStatus">0 Files Uploaded</div>
			<div>
				<input type="button" value="Upload file (Max 100 MB)" onclick="swfu.selectFiles()" style="font-size: 8pt;" />
				<input id="btnCancel" type="button" value="Cancel All Uploads" onclick="swfu.cancelQueue();" disabled="disabled" style="font-size: 8pt;" />
			</div>

	</stripes:form>
</div>
</body>
</html>

Le zip du projet eclipse avec les sources est dipo ici ->stripes-swfupload.zip