【问题标题】:The current request is not a multipart request in angularJS and Spring Rest当前请求不是 angularJS 和 Spring Rest 中的多部分请求
【发布时间】:2017-01-27 04:50:29
【问题描述】:

我正在尝试在客户端使用 AngularJS 和在服务器端使用 Spring RESTApi 上传文件,但得到 ​​p>

错误

org.springframework.web.multipart.MultipartException: The current request is not a multipart request
    at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.assertIsMultipartRequest(RequestParamMethodArgumentResolver.java:216)
    at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:167)

    .......

[http-bio-8080-exec-1] WARN org.springframework.web.servlet.PageNotFound - Request method 'POST' not supported  

Rest API

下面是一个简单的Java Post函数:

@RequestMapping(method = RequestMethod.POST)
public String saveFile(
        @RequestParam("file") MultipartFile file) {
    return "success";
}

在 Angular 中,我使用资源服务来发送请求。

Chrome 开发者工具输出

Request Payload
------WebKitFormBoundarydFRgXclyfPVixdHo
Content-Disposition: form-data; name="file"; filename="Release_Notes.txt"
Content-Type: text/plain


------WebKitFormBoundarydFRgXclyfPVixdHo--

角度服务

  function FileUploadService($resource) {
    return $resource('/fileUpload/:id', {}, {
        'save' : {
            method : 'POST',
            transformRequest: function(data, headersGetter) {
                var headers = headersGetter();
                headers['Content-Type'] = undefined;

                if (data == undefined) {
                  return data;
                }

                var fd = new FormData();

                var createKey = function(_keys_, currentKey) {
                  var keys = angular.copy(_keys_);
                  keys.push(currentKey);
                  var formKey = keys.shift()

                  if (keys.length) {
                    formKey += "[" + keys.join("][") + "]"
                  }

                  return formKey;
                };

                var addToFd = function(object, keys) {
                  angular.forEach(object, function(value, key) {
                    var formKey = createKey(keys, key);

                    if (value instanceof File) {
                      fd.append(formKey, value);
                    } else if (value instanceof FileList) {
                      if (value.length == 1) {
                        fd.append(formKey, value[0]);
                      } else {
                        angular.forEach(value, function(file, index) {
                          fd.append(formKey + '[' + index + ']', file);
                        });
                      }
                    } else if (value && (typeof value == 'object' || typeof value == 'array')) {
                      var _keys = angular.copy(keys);
                      _keys.push(key)
                      addToFd(value, _keys);
                    } else {
                      fd.append(formKey, value);
                    }
                  });
                };

                addToFd(data, []);

                return fd;
              }
          }
        });
  }

有什么提示可以避免这个错误吗?

【问题讨论】:

  • 你能显示你的 rest-servlet.xml 吗?
  • 我的项目中没有这样的文件。
  • 好的 app-context.xml 怎么样?当您使用弹簧时,它应该在那里!

标签: angularjs spring rest


【解决方案1】:

RequestParamMethodArgumentResolver 类中的方法 assertIsMultipartRequest 被调用。

该方法断言它是一个post请求并且内容类型以multipart/开头

if (!"post".equals(request.getMethod().toLowerCase())) {
        return false;
}
String contentType = request.getContentType();
return (contentType != null && contentType.toLowerCase().startsWith("multipart/"));

另一方面,您的内容类型是

Content-Type: text/plain

然后抛出异常。

【讨论】:

  • 看起来您在此处设置:headers['Content-Type'] = undefined;尝试将其设置为 multipart/form-data;
【解决方案2】:
@RequestMapping(method = RequestMethod.POST)

请求映射中缺少您的 value 属性,它应该是这样的

@RequestMapping(value="/fileupload/save/{id}" ,method = RequestMethod.POST)

并在创建角度资源时使用此代码

$resource('fileupload/save/:id',
      {id:'1'}, {
      save: {method:'POST', params:{charge:true}}
      });

在springBoot中上传文件时不需要配置太多。 但您可以将这些属性添加到您的应用程序属性文件中以更改文件大小限制。

# File size limit
multipart.maxFileSize = 3Mb

# Total request size for a multipart/form-data
multipart.maxRequestSize = 20Mb

【讨论】:

  • 我们的项目中没有使用 Spring Boot。这是一个基于 Maven 的 spring mvc 项目。关于 value 属性,在类级别,我将其定义为 @RequestMapping(value = "/api/v1/fileUpload")
【解决方案3】:

以上问题通过以下方式解决:

1) 在 WebAppConfig.java 中创建一个 MultipartResolver bean,如下所示:

@Bean
public MultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    return multipartResolver;
}

2) 将AngularJS FileUploadService(使用Resource服务)替换为http,如下图:

$http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        });

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2020-05-25
    • 2019-09-16
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 2018-06-01
    相关资源
    最近更新 更多