Java Spring MVC-使用Ajax上传多部分文件(无法解析多部分servlet请求)

Java Spring MVC-使用Ajax上传多部分文件(无法解析多部分servlet请求),java,ajax,spring,spring-mvc,multipartform-data,Java,Ajax,Spring,Spring Mvc,Multipartform Data,我试图使用Ajax、SpringMVC3.2.0、Tomcat8.0.9上传一个多部分文件,但无法正常工作。我在这里读了很多关于stackoverflow(,…)的博客和类似的帖子,它们似乎有类似的原因,但不知道如何解决它。奇怪的是,当文件小于1MB时,上传工作正常,但当录制的视频超过该大小时,会出现以下错误: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet reque

我试图使用Ajax、SpringMVC3.2.0、Tomcat8.0.9上传一个多部分文件,但无法正常工作。我在这里读了很多关于stackoverflow(,…)的博客和类似的帖子,它们似乎有类似的原因,但不知道如何解决它。奇怪的是,当文件小于1MB时,上传工作正常,但当录制的视频超过该大小时,会出现以下错误:

org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null
org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:163)
org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:110)
在以下内容中,您可以看到我所做的所有配置:

  • AJAX POST请求:

    var videoBlob = e.data;
    var pathArray = window.location.pathname.split( '/' );
    var userID;
    
    for (i = 0; i < pathArray.length; i++) {
        if (pathArray[i].toString() == "edit"){
            userID = pathArray[i+1];
        }
    }
    
    var fd = new FormData();
    fd.append('fname', 'video');
    fd.append('data', videoBlob);
    
    $.ajax({
        url: '/user/edit/uploadVideo/' + userID,
        data: fd,
        processData: false,
        contentType: false,
        type: 'POST',
        success: function(data)
        {
            $('#result').html(data + "uploaded by FormData!");
        }
    });
    
  • 我怎样才能解决这个问题

    编辑:

    我尝试了建议的方法,并使用Servlet实现来管理我的视频文件上传。已经进行了以下调整,但仍然会导致类似的错误:

  • 调整@控制器:

    @RequestMapping(value = "/edit/uploadVideo/{id}", method = RequestMethod.POST)
    public String uploadVideo(@PathVariable long id, @RequestParam("data") Part file) {
    
    //...
    }
    
  • 根控制器已被删除,我将multipartResolver添加到servlet-context.xml中

    <mvc:annotation-driven />
    <mvc:resources mapping="/**" location="/resources/" />
    
    <context:component-scan base-package="de.talentwuerfel"/>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".jsp" />
    </bean>
    
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/schema"/>
    <property name="username" value="root"/>
    <property name="password" value=""/>
    <property name="validationQuery" value="SELECT 1"/>
    </bean>
    
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="packagesToScan">
        <array>
            <value>de.talentwuerfel</value>
        </array>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>
    
    <bean id="persistenceExceptionTranslationPostProcessor"
      class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
    </bean>
    

    我实现了一个类似的文件上传,只需选择一个文件,就可以在使用相同配置的情况下发送大文件。所以我相信它与Ajax帖子或附加的blob文件有很大关系

    不是对你的确切问题的回答,只是我的2美分。借助Spring MVC,上传文件基本上有两种方式:

    • 在Servlet3.0API出现之前,使用
    • 使用服务器的实现(仅当servlet impl version>=3.0时)
    因为您使用的是Tomcat8.0.9,所以我绝对推荐使用Servet3.0选项,因为它不会在您的项目中引入另一个外部依赖项。此外,由于它遵循Servlet3.0规范,因此这种上传机制的配置现在是很好的,以防您决定从SpringMVC转移到另一个MVC框架(您的配置值将保持不变)


    如果您无法理解您的
    IOFileUploadException
    ,我认为您应该尝试一下。

    您可以在应用程序中将此添加到active Servlet3.0多路径:

     @Bean
        public MultipartConfigElement multipartConfigElement() {
            MultiPartConfigFactory factory = new MultiPartConfigFactory();
            factory.setMaxFileSize("128KB");
            factory.setMaxRequestSize("128KB");
            return factory.createMultipartConfig();
        }
    

    或者在XML中执行。

    是否尝试过将maxUploadSize参数(在filterMultipartResolver中)修改为高于100000000的值?比如说20000万编辑:对不起,我认为这是相关的,但大小以字节为单位,所以您的最大文件大小为100MB就足够了。。。已经试过了,但是没有用。下面是由AJAX请求创建的请求头:接受/接受编码gzip,deflate接受语言en US,en;q=0.5内容长度1422427内容类型多部分/表单数据;boundary=------------------------------------16605868027278490402050447340 Cookie JSESSIONID=D3611B0B660302FF7A6A2D2BD57ADDD主机localhost:8080 Referer用户代理Mozilla/5.0(Macintosh;Intel Mac OS X 10.9;rv:31.0)Gecko/20100101 Firefox/31.0 X-request-With XMLHttpRequested-谢谢你的提示,servlet impl版本是3.0,我会尝试一下!让我们知道进展如何。我提出这个解决方案的另一个原因是,我使用Servlet 3.0的方式比使用Commons FileUpload的方式更多,因此,如果使用Servlet 3.0的方式遇到任何问题,我可以提供更多帮助。我尝试了Servlet 3.0的实现,但仍然无法发送所需的文件。请看一看我附加新代码/配置的编辑问题。我觉得奇怪的是,您仍然得到一个包含“org.apache.tomcat.util.http.fileupload”的堆栈,您是否正确地从项目中删除了Commons fileupload依赖项?如果是,那一定是AJAX请求的问题。另外,请尝试在控制器的方法签名中使用org.springframework.web.multipart.MultipartFile(此->@RequestParam(“数据”)多部分文件,而不是此->@RequestParam(“数据”)部分文件)。甚至试着用一个空签名。。。因为除了从java的角度来看请求被“破坏”之外,我不明白为什么服务器端请求处理会这么早就失败(FrameworkServlet.processRequest(FrameworkServlet.java:927))。如果您使用的是Spring Boot 1.5.x,那么类名是
    org.springframework.Boot.web.servlet.MultipartConfigFactory
    (请注意小写字母“P”)
    @RequestMapping(value = "/edit/uploadVideo/{id}", method = RequestMethod.POST)
    public String uploadVideo(@PathVariable long id, @RequestParam("data") Part file) {
    
    //...
    }
    
    <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
    </bean>
    
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <location>/tmp</location>
            <max-file-size>20848820</max-file-size>
            <max-request-size>418018841</max-request-size>
            <file-size-threshold>1048576</file-size-threshold>
        </multipart-config>
    </servlet>
    
    Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:927)
        org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:822)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
        org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
    
     @Bean
        public MultipartConfigElement multipartConfigElement() {
            MultiPartConfigFactory factory = new MultiPartConfigFactory();
            factory.setMaxFileSize("128KB");
            factory.setMaxRequestSize("128KB");
            return factory.createMultipartConfig();
        }