Jersey throws NullPointerException when parsing corrupt request

java, jax-rs, jersey, rest

Solution

This seems to be a bug in Jersey. They don't check the "boundary" parameter value for `null`, before dereferencing it. You will have to find a workaround until it is fixed.

Workaround 1: Provide an `ExceptionMapper`

Maybe you can register an `ExceptionMapper` for `NullPointerException` and inspect the stack trace to test, if it is that bug or any other NPE. In case of this bug, return `4xx`, otherwise as usual `500 - internal server error`. (It's a bad hack, but I think that's ok for a temporary workaround).

Workaround 2: Provide a JAX-RS `ContainerRequestFilter`

Since JAX-RS 2.0, it is possible to provide a `ContainerRequestFilter` that is invoked before the resource method is called. Check the boundary parameter in the `Content-Type` request header. If it is absent, abort the request by calling `ContainerRequestContext#abortWith(Reponse)`.

Workaround 3: Write a servlet filter

Similar to workaround 2, but with good-old `javax.servlet.Filter`. Make sure, the filter is called before Jersey processes the request.

Problem

When sending a request with content type multipart/mixed but corrupt body (one that is no multipart), Jersey throws a `NullPointerException` while parsing the request. ``` @POST @Consumes("multipart/mixed") public Response someResource(MultiPart multiPart) { ... } ``` This results in a status code 500, while 4xx would be correct. How can I handle this exception without catching all `NullPointerExceptions`? Attachment A: stacktrace: ``` SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container java.lang.NullPointerException at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.unquoteMediaTypeParameters(MultiPartReaderClientSide.java:227) at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.readMultiPart(MultiPartReaderClientSide.java:154) at com.sun.jersey.multipart.impl.MultiPartReaderServerSide.readMultiPart(MultiPartReaderServerSide.java:80) at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:144) at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:82) at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:488) at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123) at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46) at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153) at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203) at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) at com.yammer.metrics.jersey.InstrumentedResourceMethodDispatchProvider$TimedRequestDispatcher.dispatch(InstrumentedResourceMethodDispatchProvider.java:32) at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.togglz.servlet.TogglzFilter.doFilter(TogglzFilter.java:58) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) ```

Original source