66

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,040,783
  • 362
  • 3,548
  • 3,513
atuser
  • 663
  • 1
  • 5
  • 4

3 Answers3

80

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 (Glassfish 3, Tomcat 7, etc), then you can use HttpServletRequest#getParts() instead. Also see this blog for extended examples.

Prior to Servlet 3.0, a de facto standard to parse multipart/form-data requests would be using Apache Commons FileUpload. Just carefully read its User Guide and Frequently Asked Questions sections to learn how to use it. I've posted an answer with a code example before here (it also contains an example targeting Servlet 3.0).

Community
  • 1
  • 1
BalusC
  • 1,040,783
  • 362
  • 3,548
  • 3,513
  • 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.
  • 30,765
  • 14
  • 76
  • 91
renura
  • 201
  • 2
  • 3
  • 8
    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
  • 12,891
  • 9
  • 52
  • 70
Luca Rasconi
  • 984
  • 10
  • 27
  • 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