Skip to content

Instantly share code, notes, and snippets.

@danbev
Last active December 16, 2015 05:59
Show Gist options
  • Save danbev/fec1fe498cabdf0aef6a to your computer and use it in GitHub Desktop.
Save danbev/fec1fe498cabdf0aef6a to your computer and use it in GitHub Desktop.
Multipart support in AeroGear Controller

Multipart support in AeroGear Controller

How do we want multipart support to be implemented in AeroGear Controller?

Apache Commons FileUpload

Use Apache commons-fileupload to do the heavy lifting. This would add to the size of AeroGear Controller, we could of course add this as a separate module/project which would have to be added explicitely to be include.

The target endpoints might in this case take a list of org.apache.commons.fileupload.FileItems.

For example:

route()
      .from("/mpart")
      .on(RequestMethod.POST)
      .consumes("multipart/form-data")
      .produces(JSON)
      .to(Cars.class).mpart(param(List.class));
public String mpart(final List<FileItem> fileItems) {
        String fileName = null;
        for (FileItem fileItem : fileItems) {
            if (fileItem.isFormField()) {
                // handle form field
            } else {
                // handle files
                fileName = fileItem.getName();
            }
        }
        return fileName;
    }

To invoke (assumes a file named testfile.txt exists in the current directory):

curl -i --header "Accept: application/json" \ 
-H "Content-type: multipart/form-data" \ 
-F name=testFormField -F filedata=@./testfile.txt \ 
-X POST 
"http://localhost:8080/aerogear-controller-demo/mpart"

If decided to use this approach we could make it configurable using CDI.

  • Is it acceptable to be tied to commons-fileupload?
  • Perhaps it's used so much as it might be familiar to our users

Custom Implementation

If we decide to not use Apache commons-fileupload, or anything else for that matter, and roll our own solution how do we want our endpoint methods to accept the parameters?

The "normal" way to accept form parameters is when you have fields that can be constructed into an object. The most familar example would be a Car, which is used on first page of aerogear-controller-demo. The route for this form looks like this:

route()
      .from("/cars")
      .on(RequestMethod.POST)
      .consumes(JSON, HTML)
      .produces(JSON, JSP, CUSTOM_MEDIA_TYPE)
      .to(Cars.class).save(param(Car.class));

Now, for multipart support we would need to parse the inputstream ourselves and extract the forms and files. One might have hoped that we could have used one of the getParts methods of the HttpServletRequest class, but this requires a Servlet annotated with javax.servlet.annotation.MultipartConfig. In our case we don't use a servlet but instead a ServletFilter this behaviour is undefined in this case (does not work on AS7.1 for example).

  • How would we like the endpoint methods to recieve the form fields/files?
@ZhaoYuQU
Copy link

ZhaoYuQU commented Sep 4, 2013

Can you provide a complete example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment