68

Is there any convenient way to read and parse data from incoming request.

E.g client initiate post request

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
    OutputStream output = connection.getOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!
    // Send normal param.
    writer.println("--" + boundary);
    writer.println("Content-Disposition: form-data; name=\"param\"");
    writer.println("Content-Type: text/plain; charset=" + charset);
    writer.println();
    writer.println(param);

I’m not able to get param using request.getParameter("paramName"). The following code

BufferedReader reader = new BufferedReader(new InputStreamReader(
    request.getInputStream()));
  StringBuilder sb = new StringBuilder();
  for (String line; (line = reader.readLine()) != null;) {
   System.out.println(line);

  }

however displays the content for me

-----------------------------29772313742745
Content-Disposition: form-data; name="name"
J.Doe
-----------------------------29772313742745
Content-Disposition: form-data; name="email"
abuse@spamcop.com
-----------------------------29772313742745

What is the best way to parse incoming request? I don’t want to write my own parser, probably there is a ready solution.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
atuser
  • 683
  • 1
  • 5
  • 4

3 Answers3

82

multipart/form-data encoded requests are indeed not by default supported by the Servlet API prior to version 3.0. The Servlet API parses the parameters by default using application/x-www-form-urlencoded encoding. When using a different encoding, the request.getParameter() calls will all return null. When you're already on Servlet 3.0 or newer (Glassfish 3, Tomcat 7, WildFly, etc, all introduced since December 2009 already), then you can use HttpServletRequest#getPart() instead. You can find elaboarate examples in How can I upload files to a server using JSP/Servlet?

Prior to Servlet 3.0, a de facto standard to parse multipart/form-data requests would be using Apache Commons FileUpload. You'll probably find answers and code examples using this library over all place on the Internet, but this is thus not needed anymore for more than 10 years already. Just use the standard request.getPart(name) method instead.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    Be careful. Some of the documentation on the apache site is wrong. For example they says that you can call setRepository() on a FileItemFactory object which is false because any Object that implements FileItemFactory has only one method: createItem(). So be sure you read the javadocs as well. – Cheruvim Jan 22 '14 at 23:09
  • 2
    `getParts()` always returns zero items. Why is it so hard to retrieve multipart forms in Java and Servlet 3.0? Can't believe it! – basZero Sep 23 '16 at 13:08
  • @basZero: the answer to the duplicate question already explains when it would be empty. – BalusC Sep 23 '16 at 13:15
  • @BalusC do you have a link? It's quite a lot of info here on this page – basZero Sep 23 '16 at 13:20
16

Solutions:

Solution A:

  1. Download http://www.servlets.com/cos/index.html
  2. Invoke getParameters() on com.oreilly.servlet.MultipartRequest

Solution B:

  1. Download http://jakarta.Apache.org/commons/fileupload/
  2. Invoke readHeaders() in org.apache.commons.fileupload.MultipartStream

Solution C:

  1. Download http://users.boone.net/wbrameld/multipartformdata/
  2. Invoke getParameter on com.bigfoot.bugar.servlet.http.MultipartFormData

Solution D:

Use Struts. Struts 1.1 handles this automatically.

Reference: http://www.jguru.com/faq/view.jsp?EID=1045507

Peter O.
  • 32,158
  • 14
  • 82
  • 96
renura
  • 201
  • 2
  • 3
  • 9
    Please put up some solutions as this links can get absolete any time in future. This will attract negative rating. – Jafar Ali Mar 02 '14 at 07:11
7

Not always there's a servlet before of an upload (I could use a filter for example). Or could be that the same controller ( again a filter or also a servelt ) can serve many actions, so I think that rely on that servlet configuration to use the getPart method (only for Servlet API >= 3.0), I don't know, I don't like.

In general, I prefer independent solutions, able to live alone, and in this case http://commons.apache.org/proper/commons-fileupload/ is one of that.

List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
    for (FileItem item : multiparts) {
        if (!item.isFormField()) {
            //your operations on file
        } else {
            String name = item.getFieldName();
            String value = item.getString();
            //you operations on paramters
        }
}
Dmitry Pashkevich
  • 13,431
  • 9
  • 55
  • 73
Luca Rasconi
  • 1,085
  • 11
  • 30
  • it works only when you have a request object. But what in case of stream object or any other Object data? – Ak S Nov 23 '18 at 12:27
  • The stream or any other object data will replace the request. So I would parse/read the stream or whatever in order to get the multipart form data. Anyway do you have any real example? – Luca Rasconi Nov 23 '18 at 14:03