【问题标题】:Jersey Multipart - Missing start boundaryJersey Multipart - 缺少起始边界
【发布时间】:2014-12-10 14:46:48
【问题描述】:

我有一个带有 Netty 的 jersy 2.13 的服务器应用程序,我尝试使用“multipart/form-data”上传一个文件,但出现此错误。

错误信息:

7605  10:01:49.309 [child-group-3-1] org.jvnet.mimepull.MIMEParsingException: Missing start boundary
66242 08:57:42.713 [child-group-3-1] ERROR ROOT       - No codec available to display error for 'Content-Type:multipart/form-data; boundary=----webkitformboundaryv4kegleyi4tkjp8j'

我的依赖

compile group: "org.glassfish.jersey.core",             name: "jersey-server",                  version: "2.13"
compile group: "org.glassfish.jersey.media",            name: "jersey-media-json-jackson",      version: "2.13"
compile group: "org.glassfish.jersey.media",            name: "jersey-media-multipart",         version: "2.13"

我的资源:

@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void uploadFile(@FormDataParam("file") InputStream stream, @FormDataParam("file")    FormDataContentDisposition contentDispositionHeader)
{
    System.out.println("Enter uploadFile");

    String outputPath = "C:/upload/";
    java.nio.file.Path outPath = FileSystems.getDefault().getPath(outputPath, contentDispositionHeader.getFileName());
    try
    {
        Files.copy(stream, outPath);
    }
    catch (IOException e)
    {
        throw Throwables.propagate(e);
    }
}

我的申请:

public JerseyApplication()
{
    super(JacksonMapper.class, JacksonFeature.class);

    register(new InjectionBinder());
    register(new MultiPartFeature());
    register(new MyFileUploader());
}

我的客户测试

<form action="http://localhost/api/upload" method="post" enctype="multipart/form-data">
<p><input id="uploadInput" type="file" name="file"></p>
<p><input type="submit" formenctype="multipart/form-data" value="Send file"></p>
</form>

如果我使用 jersey 1.8 (compile group: "com.sun.jersey.contribs", name: "jersey-multipart", version: "1.18.3"),如果我从函数 uploadFile 中删除 FormDataContentDisposition,它就可以工作。如果我不删除它,我会在启动时出现此错误:

    WARNING: No injection source found for a parameter of type public void com.fs.ss.communication.jersey.FileUploader.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition) at index 0.

 1621  09:39:10.974 [main] ERROR ROOT       - Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public void com.fs.ss.communication.jersey.FileUploader.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition) at index 0.; source='ResourceMethod{httpMethod=POST, consumedTypes=[multipart/form-data], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.fs.ss.communication.jersey.FileUploader, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@599545b6]}, definitionMethod=public void com.fs.ss.communication.jersey.FileUploader.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition), parameters=[Parameter [type=class java.io.InputStream, source=file, defaultValue=null], Parameter [type=class com.sun.jersey.core.header.FormDataContentDisposition, source=file, defaultValue=null]], responseType=void}, nameBindings=[]}']
 org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public void com.fs.ss.communication.jersey.FileUploader.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition) at index 0.; source='ResourceMethod{httpMethod=POST, consumedTypes=[multipart/form-data], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.fs.ss.communication.jersey.FileUploader, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@599545b6]}, definitionMethod=public void com.fs.ss.communication.jersey.FileUploader.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition), parameters=[Parameter [type=class java.io.InputStream, source=file, defaultValue=null], Parameter [type=class com.sun.jersey.core.header.FormDataContentDisposition, source=file, defaultValue=null]], responseType=void}, nameBindings=[]}']
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:467)
    at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:163)
    at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:323)
    at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
    at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
    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.processWithException(Errors.java:286)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:320)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:273)
    at com.fs.ss.communication.protocol.http.HttpJerseyServerHandler.register(HttpJerseyServerHandler.java:195)
    at com.fs.ss.communication.protocol.http.HttpServerInitializer.setJerseyResources(HttpServerInitializer.java:167)
    at com.fs.ss.communication.CommunicationService.addServer(CommunicationService.java:309)
    at com.fs.ss.communication.CommunicationService.initialize(CommunicationService.java:383)
    at com.fs.ss.communication.CommunicationService.startApp(CommunicationService.java:399)
    at com.fs.ss.communication.app.AbstractApplication.start(AbstractApplication.java:147)
    at com.fs.ss.communication.CommunicationServiceBootstrap.main(CommunicationServiceBootstrap.java:40)

如果我从uploadFile 函数中删除FormDataContentDisposition,我的文件内容如下:

------WebKitFormBoundaryATOqpm55xXBvTACH
Content-Disposition: form-data; name="file"; filename="mytxt.txt"
Content-Type: text/plain

my file content
------WebKitFormBoundaryATOqpm55xXBvTACH--

【问题讨论】:

    标签: jersey multipart jersey-2.0


    【解决方案1】:

    我在 Jersey 中遇到了类似的问题,使用 Chrome 时多部分文件上传会失败,但使用 Firefox 时会成功。

    正如 plemay 所暗示的,问题是 Chrome 在 Content-Type 标头中发送了一个包含大小写字母的边界,但服务器端的某些东西将其全部转换为小写,导致将正文解析为失败并显示“MIMEParsingException:缺少开始边界。”

    在我的情况下,原因是 Jersey 使用 SPI 在运行时加载类,并且它从 Apache CXF 获取了一个错误的 MediaType 实现,该实现将标头值转换为小写。解决方法是升级/摆脱 CXF,或强制 Jersey 使用不同的 MediaType 实现。

    更多详情请见JERSEY-1377

    【讨论】:

    • 太棒了!这让我省去了很多挫折,谢谢帕特里克!
    • 链接重定向到关闭的站点。 java.net
    【解决方案2】:

    问题在于从浏览器接收到的边界。

    Chrome 边界:boundary=----webkitformboundary2fvqbgcbynvtvptx(不工作)

    Firefox 边界:boundary=---------------------------13335242989826(工作中)

    【讨论】:

    • 嗨,我在 IE 中看到 Missing start 边界,边界如下所示。 Chome 边界工作正常。关于解决这个问题的任何想法?我正在使用最新的 mimepull.jar。内容类型多部分/表单数据;边界=---------------7e1471e600ffe
    【解决方案3】:

    这花了我大约 8 个小时来调试......然后我发现了一个简单的事实:

    boundary 应该在 content-type 中定义,如下所示:

    Content-Type: multipart/form-data; boundary=----webkitformboundary2fvqbgcbynvtvptx
    

    我希望有人能告诉我这个以节省时间......所以希望它对像我一样迷失的其他人有所帮助。

    我发现另一个帖子解决了这个问题:What is the boundary in multipart/form-data?

    【讨论】:

      【解决方案4】:

      org.jvnet.mimepull.MIMEParsingException:缺少开始边界:

      甚至,我们有正确的 Content-Type: multipart/form-data;边界=----webkitformboundary2fvqbgcbynvtvptx 出现异常。

      解决方案是:检查 web 过滤器是否有任何其他 spring multiform-data 过滤器。通过评论 spring multipart filter 进行测试,然后尝试 jersey rest upload 然后流程将按预期工作。

      注意:请确保,如果您需要两个过滤器,请更改 url-pattern 以控制同一应用程序中的 URL。

      就我而言:我评论了 org.springframework.web.multipart.support.MultipartFilter 然后它按预期工作正常。

      谢谢 拉朱萨马拉

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-24
        • 1970-01-01
        相关资源
        最近更新 更多