title: How to read several (file) inputs with the same name from a multipart form with Jersey?
body: <p>I have successfully developed a service, in which I read files uploaded in a multipart form in Jersey. Here's an extremely simplified version of what I've been doing:</p>
  
  <pre><code>@POST
  @Path("FileCollection")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  public Response uploadFile(@FormDataParam("file") InputStream uploadedInputStream,
          @FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException {
      //handle the file
  }
  </code></pre>
  
  <p>This works just fine but I've been given a new requirement. In addition to the file I'm uploading, I have to handle an arbitrary number of resources. Let's assume these are image files.</p>
  
  <p>I figured I'd just provide the client with a form with one input for the file, one input for the first image and a button to allow adding more inputs to the form (using AJAX or simply plain JavaScript).</p>
  
  <pre><code>&lt;form action="blahblahblah" method="post" enctype="multipart/form-data"&gt;
     &lt;input type="file" name="file" /&gt;
     &lt;input type="file" name="image" /&gt;
     &lt;input type="button" value="add another image" /&gt;
     &lt;input type="submit"  /&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>So the user can append the form with more inputs for images, like this:</p>
  
  <pre><code>&lt;form action="blahblahblah" method="post" enctype="multipart/form-data"&gt;
     &lt;input type="file" name="file" /&gt;
     &lt;input type="file" name="image" /&gt;
     &lt;input type="file" name="image" /&gt;
     &lt;input type="file" name="image" /&gt;
     &lt;input type="button" value="add another image" /&gt;
     &lt;input type="submit"  /&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>I hoped it would be simple enough to read the fields with the same name as a collection. I've done it successfully with text inputs in MVC .NET and I thought it wouldn't be harder in Jersey. It turns out I was wrong.</p>
  
  <p>Having found no tutorials on the subject, I started experimenting. </p>
  
  <p>In order to see how to do it, I dumbed the problem down to simple text inputs.</p>
  
  <pre><code>&lt;form action="blahblabhblah" method="post" enctype="multipart/form-data"&gt;
     &lt;fieldset&gt;
         &lt;legend&gt;Multiple inputs with the same name&lt;/legend&gt;
         &lt;input type="text" name="test" /&gt;
         &lt;input type="text" name="test" /&gt;
         &lt;input type="text" name="test" /&gt;
         &lt;input type="text" name="test" /&gt;
         &lt;input type="submit" value="Upload It" /&gt;
     &lt;/fieldset&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>Obviously, I needed to have some sort of collection as a parameter to my method. Here's what I tried, grouped by collection type.</p>
  
  <h2>Array</h2>
  
  <p>At first, I checked whether Jersey was smart enough to handle a simple array:</p>
  
  <pre><code>@POST
  @Path("FileCollection")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  public Response uploadFile(@FormDataParam("test") String[] inputs) {
      //handle the request
  }
  </code></pre>
  
  <p>but the array wasn't injected as expected.</p>
  
  <h2>MultiValuedMap</h2>
  
  <p>Having failed miserably, I remembered that <code>MultiValuedMap</code> objects could be handled out of the box. </p>
  
  <pre><code>@POST
  @Path("FileCollection")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  public Response uploadFile(MultiValuedMap&lt;String, String&gt; formData) {
      //handle the request
  }
  </code></pre>
  
  <p>but it doesn't work either. This time, I got an exception</p>
  
  <pre><code>SEVERE: A message body reader for Java class javax.ws.rs.core.MultivaluedMap, 
  and Java type javax.ws.rs.core.MultivaluedMap&lt;java.lang.String, java.lang.String&gt;, 
  and MIME media type multipart/form-data; 
  boundary=----WebKitFormBoundaryxgxeXiWk62fcLALU was not found.
  </code></pre>
  
  <p>I was told that this exception could be gotten rid of by including the <code>mimepull</code> library so I added the following dependency to my pom:</p>
  
  <pre><code>    &lt;dependency&gt;
          &lt;groupId&gt;org.jvnet&lt;/groupId&gt;
          &lt;artifactId&gt;mimepull&lt;/artifactId&gt;
          &lt;version&gt;1.3&lt;/version&gt;
      &lt;/dependency&gt;
  </code></pre>
  
  <p>Unfortunately the problem persists. It's probably a matter of choosing the right body reader and using different parameters for the generic. I'm not sure how to do this. I want to consume both file and text inputs, as well as some others (mostly <code>Long</code> values and custom parameter classes).</p>
  
  <h2>FormDataMultipart</h2>
  
  <p>After some more research, I found the <a href="http://jersey.java.net/nonav/apidocs/1.8/contribs/jersey-multipart/com/sun/jersey/multipart/FormDataMultiPart.html" rel="noreferrer">FormDataMultiPart</a> class. I've successfully used it to extract the string values from my form</p>
  
  <pre><code>@POST
  @Path("upload2")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  public Response uploadMultipart(FormDataMultiPart multiPart){
      List&lt;FormDataBodyPart&gt; fields = multiPart.getFields("test");
      System.out.println("Name\tValue");
      for(FormDataBodyPart field : fields){
          System.out.println(field.getName() + "\t" + field.getValue());
          //handle the values
      }
      //prepare the response
  }
  </code></pre>
  
  <p>The problem is, this is a solution to the simplified version of my problem. While I know that every single parameter injected by Jersey is created by parsing a string at some point (no wonder, it's HTTP after all) and I have some experience writing my own parameter classes, I don't really how to convert these fields to <code>InputStream</code> or <code>File</code> instances for further processing.</p>
  
  <p>Therefore, before diving into Jersey source code to see how these objects are created, I decided to ask here whether there is an easier way to read a set (of unknown size) of files. Do you know how to solve this conundrum?</p>