【问题标题】:Spring - AngularJS - File Upload - org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was foundSpring - AngularJS - 文件上传 - org.apache.commons.fileupload.FileUploadException:请求被拒绝,因为没有找到多部分边界
【发布时间】:2018-01-26 09:32:55
【问题描述】:

在将文件从 Angular 上传到我的 Java Spring MVC Web 应用程序服务器时,我遇到了以下异常

<form role="form" name="attachForm" class="form-horizontal" >
        <div class="form-group">
                <input class="col-xs-12" id="uploadFile" type="file" name="uploadFile" file-model ="myFile" ng-disable="closeHidden" required />
            </div>
        </div>
</form>

在我的 AngularJs 中

var saveFileURL = "caseapi/saveFile";
var fd = new FormData();
fd.append('file', scope.myFile);
return $http.post(saveFileURL,fd,{
                transformRequest: angular.identity,
                headers: {
                            "Content-Type": undefined
                        }
                });

我的指令

(function() {
define([ 'appModule'], function(app) {
app.directive('fileModel', [ '$parse', function($parse) {
    return {
        restrict : 'A',
        link : function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;
            console.log("fileModelDir");
            element.bind('change', function() {

                scope.$apply(function() {
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
} ]);
});
}).call(this);

服务器端

@RequestMapping(value = "/saveFile", method = RequestMethod.POST)
public void saveFile( MultipartFile fd, HttpServletRequest request, HttpServletResponse response) throws Exception {
    logger.info("SAVE FILE fd : " +fd);
    logger.info("File name :" + fd.getName());
    try 
    {
        /** TODO: Implement file handling **/
        logger.info("saveDraft serviceResponse: ");
        handleResponse(response, serviceResponse);

        logger.info("Exitting saveDraft");
    } catch (Exception ex) {
        logger.error("Error while calling service: ",ex);
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

}

下面是错误

SEVERE: Servlet.service() for servlet [GVEClientExperience] in context 
with path [] threw exception [Request processing failed; nested 
exception is org.springframework.web.multipart.MultipartException: 
Could not parse multipart servlet request; nested exception is 
org.apache.commons.fileupload.FileUploadException: the request was 
rejected because no multipart boundary was found] with root cause
org.apache.commons.fileupload.FileUploadException: the request was 
rejected because no multipart boundary was found
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.
<init>(FileUploadBase.java:990)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:334)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1041)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:887)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.ebaysf.web.cors.CORSFilter.handleSimpleCORS(CORSFilter.java:303)
at org.ebaysf.web.cors.CORSFilter.doFilter(CORSFilter.java:161)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:615)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1770)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1729)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

我也参考了这篇文章Spring MVC - AngularJS - File Upload - org.apache.commons.fileupload.FileUploadException 但这没有帮助。我是 Angular 的新手。想了解这里有什么问题吗?

【问题讨论】:

标签: java angularjs spring spring-mvc file-upload


【解决方案1】:

将 enctype 属性添加到您的 FORM 标记中。

<form enctype="multipart/form-data">

【讨论】:

    【解决方案2】:

    迟到但可以帮助某人:

    使用ngFileUpload,像这样:

    $scope.uploadFile = function (file, param1, param2)
    {
        var params ={'param1': param1, 'param2': param2};
    
        Upload.upload({
            url: 'http://localhost/uploadFile',
            data: {file:file},
            params: params
        }).then(function (resp) {
            console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
        }, function (resp) {
            console.log('Error status: ' + resp.status);
        }, function (evt) {
            var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
            console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
        }).catch (function onError(data){
            console.error("Upload pic exception");
            console.error(JSON.stringify(data));
     });;        
    };
    

    您也可以将参数放在数据变量中。

    【讨论】:

      【解决方案3】:

      您的请求似乎有问题。尝试这样做。

      return $http.post(saveFileURL,fd,{
                  transformRequest: angular.identity,
                  headers: {
                              "Content-Type": "multipart/form"
                          }
                  });
      

      这是 W3C 规范中提到的

      其中一个或多个不同的数据集组合在一个主体中,“多部分”Content-Type 字段必须出现在实体的标题中。

      https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

      【讨论】:

      • 感谢您的建议,但这个帮助:(
      【解决方案4】:

      您需要在控制器中指定要使用的数据类型,并使用文件的键添加请求参数

      @RequestMapping(value = "/saveFile", method = RequestMethod.POST, consumes = {"multipart/form-data"})
      public void saveFile(@RequestParam(name="fd") MultipartFile fd, HttpServletRequest request, HttpServletResponse response) throws Exception {
      

      并且不需要 contentType:undefined

       return $http.post(saveFileURL,fd,{
                  transformRequest: angular.identity,
      
                  });
      

      并在您提到的 daddygames 表单中添加加密类型

       enctype="multipart/form-data">
      

      【讨论】:

      • 嗨,我试过这个,但我得到了下面的异常。 “严重:servlet [GVEClientExperience] 在路径 [] 上下文中的 Servlet.service() 引发异常 [请求处理失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 bean 类 [org.springframework.web.multipart .MultipartFile]: Specified class is an interface] 根本原因 org.springframework.beans.BeanInstantiationException: 无法实例化 bean 类 [org.springframework.web.multipart.MultipartFile]: Specified class is an interface
      • 你的控制器使用了什么注解,spring版本是什么?
      • 我使用的是spring 3.2.9
      • 你能分享你的完整控制器吗
      • @Sheetal 我编辑了我的答案,请检查是否解决了问题,你的控制器上有 RestController 注释吗?
      【解决方案5】:

      我们已经设法使用简单而强大的第三方指令angular-upload 来处理这样的要求。使用非常简单明了。您可以在文档中找到更多详细信息。

      在 HTML 页面中:

      <div
       class="btn btn-primary btn-upload"
       upload-button
       url="/upload"
       on-success="onSuccess(response)">Upload</div>
      

      在 Angular 控制器中:

      $scope.onSuccess = function(response) {
          // Do something
      };
      

      在 Spring 控制器中:

      @RequestMapping(value = "upload", method = RequestMethod.POST)
      public void uploadAccessFile(@RequestParam("file") MultipartFile file) {
          // Do something with file
      }
      

      最后在您的配置中:

      @Bean
      public CommonsMultipartResolver multipartResolver() {
          CommonsMultipartResolver resolver = new CommonsMultipartResolver();
          resolver.setDefaultEncoding("utf-8");
          return resolver;
      }
      

      【讨论】:

        【解决方案6】:

        添加“Content-Type”:在请求中未定义,数据类型为consumes = {“multipart/form-data”})

        【讨论】:

          猜你喜欢
          • 2015-09-14
          • 2013-07-02
          • 2019-03-18
          • 1970-01-01
          • 1970-01-01
          • 2020-08-27
          • 2020-11-21
          • 1970-01-01
          • 2013-05-10
          相关资源
          最近更新 更多