title: Uploading multiple files and metadata with CXF
body: <p>I need to create a file upload handler as a REST web service with CXF.  I've been able to upload a single file with metadata using code like the following:</p>
  
  <pre><code>@POST
  @Path("/uploadImages")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  public Response uploadImage(@Multipart("firstName") String firstName,
          @Multipart("lastName") String lastName,
          List&lt;Attachment&gt; attachments) {
  
      for (Attachment att : attachments) {
          if (att.getContentType().getType().equals("image")) {
              InputStream is = att.getDataHandler().getInputStream();
              // read and store image file
          }
      }
  
      return Response.ok().build();
  }
  </code></pre>
  
  <p>Now I need to add support for uploading multiple files in the same request.  In this case, instead of an attachment with <code>image/jpeg</code> content type, I get an attachment with <code>multipart/mixed</code> content type, which itself contains the individual <code>image/jpeg</code> attachments that I need.</p>
  
  <p>I've seen examples for uploading multiple JSON or JAXB objects with metadata, but I have not been able to get anything to work with binary image data.  I have tried using the MultipartBody directly, but it only returns the <code>multipart/mixed</code> attachment, not the <code>image/jpeg</code> attachments embedded within it.</p>
  
  <p>Is there a way to recursively parse a <code>multipart/mixed</code> attachment to get the embedded attachments?  I can of course get the input stream of the <code>multipart/mixed</code> attachment, and parse out the files myself, but I'm hoping there is a better way.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>This seems kludgey, but the following bit of code is good enough for now.  I would love to see a better way though.</p>
  
  <pre><code>for (Attachment att : attachments) {
      LOG.debug("attachment content type: {}", att.getContentType().toString());
  
      if (att.getContentType().getType().equals("multipart")) {
          String ct = att.getContentType().toString();
          Message msg = new MessageImpl();
          msg.put(Message.CONTENT_TYPE, ct);
          msg.setContent(InputStream.class, att.getDataHandler().getInputStream());
          AttachmentDeserializer ad = new AttachmentDeserializer(msg, Arrays.asList(ct));
          ad.initializeAttachments();
  
          // store the first embedded attachment
          storeFile(msg.getContent(InputStream.class));
  
          // store remaining embedded attachments
          for (org.apache.cxf.message.Attachment child : msg.getAttachments()) {
              storeFile(child.getDataHandler().getInputStream());
          }
      }
      else if (att.getContentType().getType().equals("image")) {
          storeFile(att.getDataHandler().getInputStream());
      }
  }
  </code></pre>