简体   繁体   中英

Spring - AngularJS - File Upload - org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found

I am facing the below Exception while uploading a file from angular to my Java Spring MVC web application server

<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>

In my 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
                        }
                });

My Directive

(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);

Server-side

@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);
    }

}

Below is the 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)

I have as well refered to this post Spring MVC - AngularJS - File Upload - org.apache.commons.fileupload.FileUploadException but it wasnt of help. I am new to Angular. Would like to understand whats wrong here?

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

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

Late but could help somebody:

Use ngFileUpload , like this:

$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));
 });;        
};

You can also put the parameters inside the data variable.

you need to specify the data type to consume in your controller and add request param with the key of your file

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

and no need for contentType:undefined

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

            });

and add the encrypt type in your form ad daddygames mentioned

 enctype="multipart/form-data">

It seems to be a problem on your request. Try to do this.

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

Here is W3C specification mentioning it

in which one or more different sets of data are combined in a single body, a "multipart" Content-Type field must appear in the entity's header.

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

We have managed to deal with such a requirement using simple yet powerful third-party directive angular-upload . Use is pretty straightforward and simple. More details you can find in documentation.

In HTML page:

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

In Angular Controller:

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

In Spring Controller:

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

And finally in your Configuration:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM