Search code examples
jakarta-eejax-rsmultipartform-data

How to handle a multipart form request with JAX-RS. Any non-vendor specific ideas?


I am asking this question after a couple of days on research and finding no definitive answer to this question: How do I process multipart form-data requests (clean and nice) with JAX-RS (not servlets) in a vendor agnostic way?

Similar questions asked over the years:

  1. asked in 2013
  2. asked in 2019
  3. for some reason this didn't work with JakartaEE 9.1

I asked so I could as well share my best findings of a solution that I think could work.


Solution

  • I landed on this blog by Gunther Rotsch. Checkout the GitHub repo I have tested his portable solution out and so far so good. I think it is what I have been looking for. Feel feel to try it out and share your comments.

    The JAX-RS resource would look like this:

    @POST
    @Consumes("multipart/form-data")
    public Response postFormData(MultiPartMessage message) {
        ...
    }
    

    And the MessageBodyReader, the entry point of JAXRS integration like this:

    @Provider
    @Consumes("multipart/form-data")
    public class MultiPartMessageBodyReader implements MessageBodyReader<MultiPartMessage> {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(MultiPartMessageBodyReader.class);
    
    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        LOGGER.info("isReadable called with type: {} and mediaType: {}", type, mediaType);
        return MultiPartMessage.class.isAssignableFrom(type)
                && mediaType.toString().toLowerCase().startsWith("multipart/form-data");
    }
    
    @Override
    public MultiPartMessage readFrom(Class<MultiPartMessage> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException, WebApplicationException {
        ...
    }
    

    "The @Provider annotation declares the class to JAXRS, which calls this reader when the de-marshalling of messages of content type multipart/from-data is required."