Java Jersey 在解析损坏的请求时抛出 NullPointerException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20072718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jersey throws NullPointerException when parsing corrupt request
提问by Francois Bourgeois
When sending a request with content type multipart/mixedbut corrupt body (one that is no multipart), Jersey throws a NullPointerException
while parsing the request.
当发送内容类型为多部分/混合但已损坏的正文(非多部分)NullPointerException
的请求时,Jersey 会在解析请求时抛出一段时间。
@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
?
这会导致状态代码 500,而 4xx 是正确的。如何在不捕获所有异常的情况下处理此异常NullPointerExceptions
?
Attachment A: stacktrace:
附件 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)
采纳答案by isnot2bad
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.
这似乎是 Jersey 中的一个错误。null
在取消引用之前,他们不会检查 , 的“边界”参数值。在修复之前,您必须找到解决方法。
Workaround 1: Provide an ExceptionMapper
解决方法 1:提供一个 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).
也许您可以注册一个ExceptionMapper
forNullPointerException
并检查堆栈跟踪以进行测试,如果是该错误或任何其他 NPE。如果出现此错误,请返回4xx
,否则照常返回500 - internal server error
。(这是一个糟糕的黑客攻击,但我认为这可以作为临时解决方法)。
Workaround 2: Provide a JAX-RS ContainerRequestFilter
解决方法 2:提供 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)
.
从 JAX-RS 2.0 开始,可以提供在ContainerRequestFilter
调用资源方法之前调用的 。检查Content-Type
请求头中的边界参数。如果不存在,则通过调用 中止请求ContainerRequestContext#abortWith(Reponse)
。
Workaround 3: Write a servlet filter
解决方法 3:编写 servlet 过滤器
Similar to workaround 2, but with good-old javax.servlet.Filter
. Make sure, the filter is called before Jersey processes the request.
与变通方法 2 类似,但具有良好的javax.servlet.Filter
. 确保在 Jersey 处理请求之前调用过滤器。
回答by atomic_ice
The NPE occurs because the boundary parameter is missing in your call. I ran into the same problem and needed to fix the issue for my service. I ended up manually adding the boundary parameter to the Content-Type header that Jersey is expecting
出现 NPE 是因为您的调用中缺少边界参数。我遇到了同样的问题,需要解决我的服务的问题。我最终手动将边界参数添加到 Jersey 期望的 Content-Type 标头中
The fix is not pretty since the class MultipartFormEntity is package private however it works well.
修复不是很好,因为类 MultipartFormEntity 是包私有的,但它运行良好。