Search code examples
javafile-uploadgwtmultipartform-dataformpanel

In GWT, is Multipart form-data guaranteed to be sent in the order it is on the form?


I have a form built with FormPanel and three FileUpload objects. The three FileUpload objects refer to different types of binary files. I've tested quite a bit, and the files have always been placed in the list in the order that I've added them (from top to bottom) in the three FileUpload objects. So, for example, in the form below the files 1, 2 and 3 arrive at the server in that order (I've ran it with various files 20 or 30 times):

file upload example

Is that guaranteed? or should I find a way to label them somehow?


Solution

  • When using the FileItemIterator you can check each item on the form. As far as I'm aware of they do come in order they are in the HTML.

    The iterator will let you know if it is a form field or an upload file as shown in an old function I wrote.

    On handling a file upload, use getFieldName() to identify the form field and getName() to handle the filename from the client.

    The difficulty is assigning the servlet in the parameters in the web.xml file.

    Hopefully the following code will help you figure it out.

    public class FileUploadServlet extends HttpServlet {
    
        private static final long serialVersionUID = -6988332690679764038L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doGet(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                throws IOException {
    
            String path = "/home/tomcat/engage/media/";
            String user = "";
    
            if (ServletFileUpload.isMultipartContent(request)) {
    
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);
    
                boolean gotPath = false;
    
                String message = "";
                String media_category = "";
    
                StringBuilder sb = new StringBuilder();
                sb.append(Shared.getTimeStamp() + ": Uploading med files to category - ");
    
                try {
                    FileItemIterator it = upload.getItemIterator(request);
    
                    while (it.hasNext()) {
                        FileItemStream item = it.next();
    
                        //message += item.getFieldName() + ": ";
    
                        if (item.isFormField()) {
                            if (item.getFieldName().equals("MediaCategory")) {
                                media_category = Streams.asString(item.openStream());
                                path += media_category;
    
                                gotPath = true;
    
                                message += path + System.lineSeparator();
    
                            } else if (item.getFieldName().equals("UserName")) {
    
                                user += Streams.asString(item.openStream());
    
                            }
                        } else {
                            if (gotPath) {
                                String fileout = path + "/" + item.getName();
    
                                message += fileout + System.lineSeparator();
    
                                InputStream input = null;
                                OutputStream output = null;
    
                                try {
                                    output = new FileOutputStream(new File(fileout));
    
                                    input = item.openStream();
    
                                    byte[] buffer = new byte[256];
                                    int count;
    
                                    while ((count = input.read(buffer)) > 0) {
                                        output.write(buffer, 0, count);
                                    }
    
                                } finally {
                                    input.close();
                                    output.close();
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    response.sendRedirect("Error on item: " + e.getLocalizedMessage());
                }
    
                response.setStatus(HttpServletResponse.SC_CREATED);
    
                //response.getWriter().print(message);
    
                sb.append(message + System.lineSeparator());
                Shared.writeUserLog(user, sb.toString());
    
            } else {
                response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, 
                        "Unsupported media type...");
            }
    
        }
    }
    

    web.xml

    <context-param>
        <!-- max size of the upload request -->
        <param-name>maxSize</param-name>
        <param-value>3145728</param-value>
    </context-param>
    <context-param>
        <!-- max size of any uploaded file -->
        <param-name>maxFileSize</param-name>
        <param-value>1024000</param-value>
    </context-param>
    <context-param>
        <!-- Useful in development mode to slow down the uploads in fast networks. 
            Put the number of milliseconds to sleep in each block received in the server. 
            false or 0, means don't use slow uploads -->
        <param-name>slowUploads</param-name>
        <param-value>200</param-value>
    </context-param>
    
    <servlet>
        <servlet-name>fileUpload</servlet-name>
        <servlet-class>com.parity.mediamanager.server.FileUploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>fileUpload</servlet-name>
        <url-pattern>/fileupload</url-pattern>
    </servlet-mapping>
    

    I know the servlet settings work but I'm still unsure about the context params and if they actually make a difference.