Configuring a resource to receive multipart/form-data parts from an HTML form submission in JAX-RS 2.0

HTML forms that transmit file data must be configured with the POST method and the "multipart/form-data" action. The resource method executing in IBM's implementation of the Java™ API for RESTful Web Services (JAX-RS) specification can receive this data in one of the two ways.

About this task

Open Liberty Documentation for JAX-RS 2.0 and later is available on the Open Liberty website.

This task provides instructions for configuring a JAX-RS method to use and produce multipart/form-data. The following example illustrates an HTML form:
<form action="http://www.example.com/" method="POST" enctype="multipart/form-data">
    <input type="text" name="fileid" />
    <br />
    <input type="text" name="description" />
    <br />
    <input type="file" name="thefile" />
    <br />
    <input type="submit" name="submit" value="submit"/>
</form>
You can implement your JAX-RS resource method to receive the data in parts, so you can process these parts yourself, if needed.

Procedure

Create a resource method.
You must declare one of the following resource methods to receive and echo multipart/form-data content from an HTTP POST:

@POST
@Consumes("multipart/form-data")
@Produces("multipart/form-data")

public Response postFormData(IMultipartBody multipartBody) {
    List <IAttachment> attachments = multipartBody.getAllAttachments();
    String formElementValue = null; 
    InputStream stream = null;
    for (Iterator<IAttachment> it = attachments.iterator(); it.hasNext();) {
         IAttachment attachment = it.next();
         if (attachment == null) {
             continue;
         }
         DataHandler dataHandler = attachment.getDataHandler();
         stream = dataHandler.getInputStream();
         MultivaluedMap<String, String> map = attachment.getHeaders();
         String fileName = null;
         String formElementName = null;
         String[] contentDisposition = map.getFirst("Content-Disposition").split(";");
         for (String tempName : contentDisposition) {
              String[] names = tempName.split("=");
              formElementName = names[1].trim().replaceAll("\"", "");
              if ((tempName.trim().startsWith("filename"))) {
                   fileName = formElementName;
              }
         }
         if (fileName == null) {
             StringBuffer sb = new StringBuffer();
             BufferedReader br = new BufferedReader(new InputStreamReader(stream));
             String line = null;
             try {
                 while ((line = br.readLine()) != null) {
                    sb.append(line);
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             } finally {
                 if (br != null) {
                     try {
                          br.close();
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
                 }
             }
             formElementValue = sb.toString();
             System.out.println(formElementName + ":" + formElementValue);
         } else {
             //handle the file as you want
             File tempFile = new File(fileName);
             ...
         }
    }
    if (stream != null) {
        stream.close();
    }
    return Response.ok("test").build();
}
Or

@POST
@Consumes("multipart/form-data")
@Produces("multipart/form-data")

public Response postFormData(IMultipartBody multipartBody) {
    List <IAttachment> attachments = multipartBody.getAllAttachments();
    String formElementValue = null; 
    InputStream stream = null;
    for (Iterator<IAttachment> it = attachments.iterator(); it.hasNext();) {
         IAttachment attachment = it.next();
         if (attachment == null) {
             continue;
         }
         DataHandler dataHandler = attachment.getDataHandler();
         stream = dataHandler.getInputStream();
         MultivaluedMap<String, String> map = attachment.getHeaders();
         String fileName = null;
         String formElementName = null;
         String[] contentDisposition = map.getFirst("Content-Disposition").split(";");
         for (String tempName : contentDisposition) {
             String[] names = tempName.split("=");
             formElementName = names[1].trim().replaceAll("\"", "");
             if ((tempName.trim().startsWith("filename"))) {
                 fileName = formElementName;
             }
         }
         if (fileName == null) {
             StringBuffer sb = new StringBuffer();
             BufferedReader br = new BufferedReader(new InputStreamReader(stream));
             String line = null;
             try {
                 while ((line = br.readLine()) != null) {
                     sb.append(line);
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             } finally {
                 if (br != null) {
                     try {
                         br.close();
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
                 }
             }
             formElementValue = sb.toString();
             System.out.println(formElementName + ":" + formElementValue);
         } else {
             //handle the file as you want
             File tempFile = new File(fileName);
             ...
         }
    }
    if (stream != null) {
        stream.close();
    }
    return Response.ok("test").build();
}
The originator of the form POST submission can generate a Content-Transfer-Encoding header for one or more parts of the multipart message. The IBM JAX-RS implementation attempts to auto-decode the payload of the part according to this header when the header is of base64 or quoted-printable encoding type.

Results

Your resource method will receive and echo data from an HTTP POST with multipart/form-data Content-Type. IBM's JAX-RS implementation will split and auto-decode the parts for you, allowing the application code in the resource method to process the form data.