0

I have a REST service hosted inside Karaf, which is working fine with all requests except for multipart requests. I'm using the com.sun.jersey packages, as I have only succeeded in hosting these inside of Karaf to be accessed over HTTP.

When I try to receive the HttpServletRequest inside the POST and call the getParts() method on it, I get the error:

IllegalStateException: No multipart config for servlet

I have found that I am missing the @MultipartConfig annotation on my servlet, so I added this to the servlet implementation I am using. I extend com.sun.jersey.spi.container.servlet.ServletContainer and add the annotation to that class. But this does not work.

I've also tried using my own extension of the HttpServlet class, that reproduces the error:

@MultipartConfig
public class MultipartServlet extends HttpServlet {

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {

        try {
            final HttpServletRequest httpRequest = (HttpServletRequest)request;
            final Collection<Part> parts = httpRequest.getParts();

            System.out.println("There are " + parts.size() + " parts");
        }
        catch (Exception exception) {
            System.out.println("MEGA FAIL");
            System.out.println(exception.getMessage());
        }

        super.service(request, response);
    }
}

I've seen the approach using org.glassfish.jersey packages that makes registers the MultiPartFeature class with the ResourceConfig, but I haven't been able to get these packages accessible over HTTP inside of Karaf (the services appear to register without error, but all requests return 404 responses).

Samuel Slade
  • 8,405
  • 6
  • 33
  • 55
  • Why are you trying to use multipart in a servlet when you want to do it with Jersey. See [this article](https://www.mkyong.com/webservices/jax-rs/file-upload-example-in-jersey/) for Jersey 1.x multipart support – Paul Samsotha Aug 30 '17 at 13:47
  • That article uses specifically named parts from the multipart request. I need to be able to handle an unknown number of parts within the body of the method itself, which is why I was trying to use the `HttpServletRequest`. Is there a way to achieve this using Jersey instead? – Samuel Slade Aug 30 '17 at 15:49
  • @peeskillet It's probably also worth highlighting that I'm running this inside of Karaf, so I've got this servlet registered against the `HttpService` installed with Karaf, as that was the only way I had managed to host a RESTful service within Karaf that was accessible via HTTP (i.e. on localhost:8181). If there's a better way of approaching that, then any direction would be appreciated – Samuel Slade Aug 30 '17 at 15:55
  • _"I need to be able to handle an unknown number of parts within the body of the method itself"_ - Use [FormDataMultiPart](https://github.com/jersey/jersey-1.x/blob/master/contribs/jersey-multipart/src/main/java/com/sun/jersey/multipart/FormDataMultiPart.java#L85) as the method parameter. You don't need to use any annotations. – Paul Samsotha Aug 30 '17 at 16:22
  • @peeskillet I'm guessing I'm missing something, but when trying to use that as the method parameter of the service with no annotations I get a **400 Bad Request** response. Any idea what I might be missing? – Samuel Slade Aug 30 '17 at 16:37
  • @peeskillet Never mind, I fixed the Bad Request response by removing the `Content-Type` header in the request (for some reason). So the `FormDataMultiPart` is now working :-) Feel free to post that as an answer and I'll mark it as accepted – Samuel Slade Aug 30 '17 at 16:55

1 Answers1

1

Instead of trying to use the Servlet multipart, you just use Jersey's multipart support. In the example in the link, it uses named parts. If you want to be able to process all unknown parts, you can just use FormDataMultiPart as the method parameter. This way you can access all the parts with getFields()

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response post(FormDataMultiPart multiPart) {
    final Map<String, List<FormDataBodyPart>> = multiPart.getFields();
}
Samuel Slade
  • 8,405
  • 6
  • 33
  • 55
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720