Wednesday, December 28, 2011

Multiple File Upload Examples

I received an email today from a developer who was looking for examples of how to do multiple file uploads. I had written a post previously Multiple File Upload Options which detailed some of the options available. The option I recommended was Andrew Valums ajax-upload. The developer had indicated that the servlet I contributed was not working with Internet Explorer correctly. He was correct.

The code that I provided to Andrew Vallums was expecting application/octet-stream. However Internet Explorer and Opera were sending multipart/form-data. This would not work with the servlet example I posted since the handling mechanism is considerably different.

Alan O'Driscoll and I discovered the differences using Wireshark to sniff the packets and see what was being sent over the wire. As a result, I have written a new servlet to handle the differences between browsers.

The example application I wrote has a number of different examples included with minor variations on the theme. The version most folks are interested in is example #6 which uses the ajax-upload, and the new servlet. Here is the Apache Maven project which was developed on NetBeans and tested on GlassFish v 2.1.1.

Here is a link to the Mercurial project: apache-file-upload-ee5.

Here is another resource for file upload plugins: 9 Powerful jQuery File Upload Plugins. I discovered it while I was looking for something else.

MultiContentServlet.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.bluelotussoftware.apache.commons.fileupload.example;
 
import java.io.*;
import java.util.List;
import java.util.ListIterator;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
 
/**
 *
 * @author John Yeary
 * @author Allan O'Driscoll
 * @version 1.0
 */
public class MultiContentServlet extends HttpServlet {
 
    private static final long serialVersionUID = -2045199313944348406L;
    private static final String DESTINATION_DIR_PATH = "files";
    private static String realPath;
    private static final boolean debug = false;
 
    /**
     * {@inheritDoc}
     *
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH) + "/";
    }
 
    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter writer = null;
        InputStream is = null;
        FileOutputStream fos = null;
 
        try {
            writer = response.getWriter();
        } catch (IOException ex) {
            log(MultiContentServlet.class.getName() + "has thrown an exception: " + ex.getMessage());
        }
 
        boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
 
        if (isMultiPart) {
            log("Content-Type: " + request.getContentType());
            // Create a factory for disk-based file items
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
 
            /*
             * Set the file size limit in bytes. This should be set as an
             * initialization parameter
             */
            diskFileItemFactory.setSizeThreshold(1024 * 1024 * 10); //10MB.
 
 
            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(diskFileItemFactory);
 
            List items = null;
 
            try {
                items = upload.parseRequest(request);
            } catch (FileUploadException ex) {
                log("Could not parse request", ex);
            }
 
            ListIterator li = items.listIterator();
 
            while (li.hasNext()) {
                FileItem fileItem = (FileItem) li.next();
                if (fileItem.isFormField()) {
                    if (debug) {
                        processFormField(fileItem);
                    }
                } else {
                    writer.print(processUploadedFile(fileItem));
                }
            }
        }
 
        if ("application/octet-stream".equals(request.getContentType())) {
            log("Content-Type: " + request.getContentType());
            String filename = request.getHeader("X-File-Name");
 
            try {
                is = request.getInputStream();
                fos = new FileOutputStream(new File(realPath + filename));
                IOUtils.copy(is, fos);
                response.setStatus(HttpServletResponse.SC_OK);
                writer.print("{success: true}");
            } catch (FileNotFoundException ex) {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                writer.print("{success: false}");
                log(MultiContentServlet.class.getName() + "has thrown an exception: " + ex.getMessage());
            } catch (IOException ex) {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                writer.print("{success: false}");
                log(MultiContentServlet.class.getName() + "has thrown an exception: " + ex.getMessage());
            } finally {
                try {
                    fos.close();
                    is.close();
                } catch (IOException ignored) {
                }
            }
 
            writer.flush();
            writer.close();
        }
    }
 
    private void processFormField(FileItem item) {
        // Process a regular form field
        if (item.isFormField()) {
            String name = item.getFieldName();
            String value = item.getString();
            log("name: " + name + " value: " + value);
        }
    }
 
    private String processUploadedFile(FileItem item) {
        // Process a file upload
        if (!item.isFormField()) {
            try {
                item.write(new File(realPath + item.getName()));
                return "{success:true}";
            } catch (Exception ex) {
                log(FileUploadServlet.class.getName() + " has thrown an exception: " + ex.getMessage());
            }
        }
        return "{success:false}";
    }
 
    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Handles file upload data from application/octet-stream, and multipart/form-data.";
    }
}

0 comments :

Popular Posts