java - Jersey 在解析损坏的请求时抛出 NullPointerException

标签 java rest jersey jax-rs

当发送内容类型为 multipart/mixed 但正文已损坏(没有多部分)的请求时,Jersey 在解析请求时抛出 NullPointerException

@POST
@Consumes("multipart/mixed")
public Response someResource(MultiPart multiPart) { ... }

这会导致状态代码 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)

最佳答案

This seems to be a bug in Jersey .在取消引用之前,他们不检查 null 的“边界”参数值。在修复之前,您必须找到解决方法。

解决方法 1:提供 ExceptionMapper

也许您可以为 NullPointerException 注册一个 ExceptionMapper 并检查堆栈跟踪以测试它是否是该错误或任何其他 NPE。如果出现此错误,返回 4xx,否则像往常一样返回 500 - 内部服务器错误。 (这是一个糟糕的 hack,但我认为这对于临时解决方法来说是可以的)。

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

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

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

类似于解决方法 2,但使用了很好的旧 javax.servlet.Filter。确保在 Jersey 处理请求之前调用过滤器。

关于java - Jersey 在解析损坏的请求时抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20072718/

相关文章:

wcf - 通过 WCF REST 传递验证异常

jakarta-ee - JAX-RS Jersey : @XmlElementWrapper returns

java - Camel 丰富和聚合策略

java - PostInsertEventListener 在数据库更新之前执行

java - IntelliJ cucumber .ClassNotFoundException

java - 将 Jersey 本地 REST 服务引入 openshift

java - 事务如何与多个持久性单元一起工作

java - 并发编程是更加网格化还是更加集群化?

javascript - 向本地主机发送请求时,jQuery xhr.status 返回 0

java - 使用 Eclipse、JBoss 7.1.1 和 Jersey 1 获取 ClassNotFoundException