DWR + Maven2 + upload progress bar

DWR + Maven2 + upload progress bar

DWR est un framework qui s'incrit un peu dans la logique de GWT, dans le sens ou l'on manipule des objets Java via du javascript. Dans cet exemple je vais illustrer comment 

utiliser DWR avec Stripes pour construire une bar de progression dans le cadre de l'upload d'un fichier.

Implémentation d'un MultipartWrapper.

Afin de pouvoir utiliser les mécanismes de listener offerts par commons-fileupload, j'ai modifié l'implémentation du Wrapper standard proposé par Stripes.

J'ai donc modifier la méthode build pour ajouter un listerner sur le ServletFileUpload. Ce listener est implémenté dans le paragraphe suivant.

 
public void build(HttpServletRequest request, File tempDir, long maxPostSize) throws IOException, FileUploadLimitExceededException { 
        try { 
            this.charset = request.getCharacterEncoding(); 
            DiskFileItemFactory factory = new DiskFileItemFactory(); 
            factory.setRepository(tempDir); 
            ServletFileUpload upload = new ServletFileUpload(factory); 
            upload.setSizeMax(maxPostSize); 
            
            // Adding the listener 
            upload.setProgressListener(new UploadProgressListener()); 
            List<FileItem> items = upload.parseRequest(request); 
            Map<String, List<String>> params = new HashMap<String, List<String>>(); 

            for (FileItem item : items) { 
                // If it's a form field, add the string value to the list 
                if (item.isFormField()) { 
                    List<String> values = params.get(item.getFieldName()); 
                    if (values == null) { 
                        values = new ArrayList<String>(); 
                        params.put(item.getFieldName(), values); 
                    } 
                    values.add(charset == null ? item.getString() : item.getString(charset)); 
                } 
                // Else store the file param 
                else { 
                    files.put(item.getFieldName(), item); 
                } 
            } 

            // Now convert them down into the usual map of String->String[] 
            for (Map.Entry<String, List<String>> entry : params.entrySet()) { 
                List<String> values = entry.getValue(); 
                this.parameters.put(entry.getKey(), values.toArray(new String[values.size()])); 
            } 
        } catch (FileUploadBase.SizeLimitExceededException slee) { 
            throw new FileUploadLimitExceededException(maxPostSize, slee.getActualSize()); 
        } catch (FileUploadException fue) { 
            IOException ioe = new IOException("Could not parse and cache file upload data."); 
            ioe.initCause(fue); 
            throw ioe; 
        } 
    } 

 

Implémentation du Listener :

 
package com.fullsix.demo.dwr; 

import java.text.NumberFormat; 

import org.apache.commons.fileupload.ProgressListener; 

/** 
 * @author Damien Viel <viel@fullsix.com> 
 * @version $Id$ 
 * 
 */ 
public class UploadProgressListener implements ProgressListener { 

    private static long bytesTransferred = 0; 
    private static long fileSize = -100; 
    private long tenKBRead = -1; 

    public String getFileUploadStatus() { 
        String per = NumberFormat.getPercentInstance().format((double) bytesTransferred / (double) fileSize); 
        return per.substring(0, per.length() - 1); 
    } 

    public void update(long bytesRead, long contentLength, int items) { 
        long tenKB = bytesRead / 10240; 
        if (tenKBRead == tenKB) 
            return; 
        tenKBRead = tenKB; 

        bytesTransferred = bytesRead; 
        if (fileSize != contentLength) 
            fileSize = contentLength; 
    } 
} 

Configuration DWR :

Dans le répertoire WEB-INF de votre webapp, creer un fichier dwr.xml.

 
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" 
                     "http://getahead.org/dwr//dwr20.dtd"> 

<dwr> 
    <allow> 
        <create creator="new" javascript="UploadProgressListener"> 
            <param name="class" value="com.fullsix.demo.dwr.UploadProgressListener" /> 
            <include method="getFileUploadStatus"/> 
        </create> 
    </allow> 
</dwr> 

Fichier web.xml

Utiliser le nouveau MultipartWrapper et déclarer le servlet DWR.

 
 <?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>com.fullsix.demo.dwr.CommonsDWRMultipartWrapper</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> 
        <servlet-name>dwr-invoker</servlet-name> 
        <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> 
        <init-param> 
            <param-name>debug</param-name> 
            <param-value>false</param-value> 
        </init-param> 
        <init-param> 
            <param-name>logLevel</param-name> 
            <param-value>WARN</param-value> 
        </init-param> 
    </servlet> 

    <servlet-mapping> 
        <servlet-name>dwr-invoker</servlet-name> 
        <url-pattern>/dwr/*</url-pattern> 
    </servlet-mapping> 

    <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> 

Fichier JSP :

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

<html xmlns="http://www.w3.org/1999/xhtml" > 
    <head> 
        <title>DWR Demo</title> 
        <link href="css/default.css" rel="stylesheet" type="text/css" /> 
        <script src="${pageContext.request.contextPath}/dwr/engine.js"></script> 
        <script src="${pageContext.request.contextPath}/dwr/util.js"></script>
        <script src="${pageContext.request.contextPath}/dwr/interface/UploadProgressListener.js"></script> 
        
            <script type="text/javascript"> 
                function startProgress() { 
                    document.getElementById('progressBar').style.display = 'block'; 
                    document.getElementById('progressBarText').innerHTML = 'Progression : 0%'; 
                    window.setTimeout('fileupload_ajax_query_upload_status()', 1500); 
                    return true; 
                } 
                
                function fileupload_ajax_query_upload_status() { 
                    UploadProgressListener.getFileUploadStatus(fileupload_ajax_show_upload_status);
                    return true; 
                } 
                
                function fileupload_ajax_show_upload_status(status) { 
                  document.getElementById("progressBar").style.display = "block"; 
                  document.getElementById("progressBarText").innerHTML = "Progression : " + status + "%"; 
                  document.getElementById("progressBarBoxContent").style.width = parseInt(status * 3.5) + "px"; 
                  window.setTimeout('fileupload_ajax_query_upload_status()', 200); 
                  return true; 
                } 
            </script> 
    </head> 
    <body> 
        <div id="content"> 
            <h2>Simple Demo</h2> 
            <stripes:form beanclass="com.fullsix.demo.action.UploadActionBean" onsubmit="startProgress();"> 
                <h1>Web upload</h1> 
                <p> 
                    <stripes:file id="fileBean" name="fileBean" /> 
                    <br /> 
                    <stripes:submit value="begin upload" id="uploadbutton" name="upload" /> 
                    <br /> 
                    <div id="progressBar" style="display: none;"> 
                        <div id="progressBarText"></div> 
                        <div id="progressBarBox"> 
                            <div id="progressBarBoxContent"></div> 
                        </div> 
                    </div> 
                </p> 
            </stripes:form> 
        </div> 
    </body> 
</html> 

Le pom.xml 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>demodwr</artifactId> 
    <packaging>war</packaging> 
    <name /> 
    <version>0.0.1-SNAPSHOT</version> 
    <description /> 
    <build> 
        <finalName>demoDWR</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>org.directwebremoting</groupId> 
            <artifactId>dwr</artifactId> 
            <version>2.0.2</version> 
        </dependency> 
        <dependency> 
            <groupId>commons-lang</groupId> 
            <artifactId>commons-lang</artifactId> 
            <version>2.4</version> 
        </dependency> 
    </dependencies> 
</project>