在解析损坏的请求时,Jersey会抛出NullPointerException

Fra*_*ois 5 java rest jax-rs jersey

当发送具有内容类型multipart/mixed但是损坏的主体(一个不是多部分)NullPointerException的请求时,Jersey会抛出一段时间来解析请求.

@POST
@Consumes("multipart/mixed")
public Response someResource(MultiPart multiPart) { ... }
Run Code Online (Sandbox Code Playgroud)

这导致状态代码500,而4xx将是正确的.如何在不捕获所有异常的情况下处理此异常NullPointerExceptions

附件A:堆栈跟​​踪:

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)
Run Code Online (Sandbox Code Playgroud)

isn*_*bad 6

这似乎是泽西岛的一个错误.null在解除引用之前,它们不检查"boundary"参数值.在修复之前,您必须找到解决方法.

解决方法1:提供 ExceptionMapper

也许你可以注册一个ExceptionMapperfor NullPointerException并检查堆栈跟踪来测试,如果是那个bug或任何其他NPE.如果出现此错误,请返回4xx,否则照常500 - internal server error.(这是一个糟糕的黑客,但我认为这对临时解决方案是可行的).

解决方法2:提供JAX-RS ContainerRequestFilter

从JAX-RS 2.0开始,可以提供在ContainerRequestFilter调用资源方法之前调用的方法.检查Content-Type请求标头中的边界参数.如果不存在,请通过呼叫中止请求ContainerRequestContext#abortWith(Reponse).

解决方法3:编写servlet过滤器

类似于解决方法2,但与旧的相比javax.servlet.Filter.确保在Jersey处理请求之前调用过滤器.