带有 WebKit 浏览器(Chrome、Safari)的 jersey 2.15 缺少起始边界

Missing start boundary with jersey 2.15 with WebKit browser (Chrome, Safari)

我有一个带有 netty et jersey 2.15 的 java 应用程序。 我尝试上传一个包含多个部分的文件。

<form id="data" enctype="multipart/form-data" method="post" action="http://localhost/api/upload">>
        Profile Image: <input name="file" type="file" /><br />
        <input type="submit" value="Submit">
</form>

它适用于 Firefox 和 IE,但不适用于 Chrome 或 Safari

注意。 Chrome 和 Safari 使用 Webkit。

在 Firefox 上查看数据(在 IE 上相同)

//startContent
-----------------------------2382551017519
Content-Disposition: form-data; name="file"; filename="foo.txt"
Content-Type: text/plain

bar
-----------------------------2382551017519--

//endContent

//byte
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 51, 56, 50, 53, 53, 49, 48, 49, 55, 53, 49, 57, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 68, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 58, 32, 102, 111, 114, 109, 45, 100, 97, 116, 97, 59, 32, 110, 97, 109, 101, 61, 34, 102, 105, 108, 101, 34, 59, 32, 102, 105, 108, 101, 110, 97, 109, 101, 61, 34, 102, 111, 111, 46, 116, 120, 116, 34, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 13, 10, 13, 10, 98, 97, 114, 13, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 51, 56, 50, 53, 53, 49, 48, 49, 55, 53, 49, 57, 45, 45, 13, 10

//header
Host : localhost
User-Agent : Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept : */*
Accept-Language : fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding : gzip, deflate
Referer : http://10.0.16.56:8080/
Origin : http://10.0.16.56:8080
Connection : keep-alive
Pragma : no-cache
Cache-Control : no-cache
Content-Length : 188
Content-Type : multipart/form-data; boundary=---------------------------2382551017519

查看 Chrome 上的数据(在 Safari 上相同)

//[startContent]
------WebKitFormBoundaryg7okV37G7Gfll2hf
Content-Disposition: form-data; name="file"; filename="foo.txt"
Content-Type: text/plain

bar
------WebKitFormBoundaryg7okV37G7Gfll2hf--

//[endContent]

//byte
45, 45, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 103, 55, 111, 107, 86, 51, 55, 71, 55, 71, 102, 108, 108, 50, 104, 102, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 68, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 58, 32, 102, 111, 114, 109, 45, 100, 97, 116, 97, 59, 32, 110, 97, 109, 101, 61, 34, 102, 105, 108, 101, 34, 59, 32, 102, 105, 108, 101, 110, 97, 109, 101, 61, 34, 102, 111, 111, 46, 116, 120, 116, 34, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 13, 10, 13, 10, 98, 97, 114, 13, 10, 45, 45, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 103, 55, 111, 107, 86, 51, 55, 71, 55, 71, 102, 108, 108, 50, 104, 102, 45, 45, 13, 10

//header
Host : localhost
User-Agent : Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Accept : */*
Accept-Language : fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Encoding : gzip, deflate
Referer : http://10.0.16.56:8080/
Origin : http://10.0.16.56:8080
Connection : keep-alive


Content-Length : 184
Content-Type : multipart/form-data; boundary=----webkitformboundaryg7okv37g7gfll2hf

//ERROR
36691 10:04:19.945 [event-group-5-8] INFO  .c.p.h.HttpJerseyServerHandler - Invoking '/api/nonJaxbResource/upload'
36695 10:04:19.949 [child-group-3-8] WARN  http-server - 58b3f632-6fa3-4a7b-98e7-4ef13e511550 | Missing start boundary
36695 10:04:19.949 [child-group-3-8] ERROR ROOT       - No codec available to display error for 'Content-Type:multipart/form-data; boundary=----webkitformboundaryg7okv37g7gfll2hf'
59215 13:27:52.642 [event-group-5-3] ERROR ROOT       - HTTP 400 Bad Request
 javax.ws.rs.BadRequestException: HTTP 400 Bad Request
    at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:184)
    at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:91)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:258)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:234)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:73)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)
    at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:233)
    at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider.getEntity(FormDataParamValueFactoryProvider.java:376)
    at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider.access[=13=]0(FormDataParamValueFactoryProvider.java:87)
    at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider$FormDataParamValueFactory.provide(FormDataParamValueFactoryProvider.java:203)
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:136)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:384)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:342)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
    at org.glassfish.jersey.server.JerseyApplicationHandlerRuntime.run(JerseyApplicationHandlerRuntime.java:229)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:316)
    at org.glassfish.jersey.server.JerseyApplicationHandlerRuntime.process(JerseyApplicationHandlerRuntime.java:208)
    at org.glassfish.jersey.server.JerseyApplicationHandler.handle(JerseyApplicationHandler.java:1019)
    ...
Caused by: org.jvnet.mimepull.MIMEParsingException: Missing start boundary
    at org.jvnet.mimepull.MIMEParser.skipPreamble(MIMEParser.java:313)
    at org.jvnet.mimepull.MIMEParser.access0(MIMEParser.java:68)
    at org.jvnet.mimepull.MIMEParser$MIMEEventIterator.next(MIMEParser.java:149)
    at org.jvnet.mimepull.MIMEParser$MIMEEventIterator.next(MIMEParser.java:132)
    at org.jvnet.mimepull.MIMEMessage.makeProgress(MIMEMessage.java:198)
    at org.jvnet.mimepull.MIMEMessage.parseAll(MIMEMessage.java:181)
    at org.jvnet.mimepull.MIMEMessage.getAttachments(MIMEMessage.java:106)
    at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readMultiPart(MultiPartReaderClientSide.java:225)
    at org.glassfish.jersey.media.multipart.internal.MultiPartReaderServerSide.readMultiPart(MultiPartReaderServerSide.java:90)
    at org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:179)
    ... 36 common frames omitted

我发现了问题。一位同事在 netty 实现中将每个请求的内容类型转换为小写。 none WebKit 浏览器使用随机数字边界,而 WebKit 浏览器使用带有大小写字符的字母数字边界。