【问题标题】:Multipart post request from Angular To Spring从 Angular 到 Spring 的多部分发布请求
【发布时间】:2021-03-23 19:58:19
【问题描述】:

我在这里尝试将一些数据从 Angular App 发布到 Spring Boot 后端,不幸的是,我被一个难以理解的错误困扰了一天,

这是我的 API

@PostMapping("/add", consumes = ["multipart/form-data"])
fun addTeam(
    @RequestPart(name = "file") file: MultipartFile,
    @RequestPart(name = "body") team: Team
): ResponseEntity<*> {
    val imgUrl = filesStorageService.storeFile(file)

    val fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
        .path("/storage/downloadFile/")
        .path(imgUrl)
        .toUriString()


    val list = teamService.addTeam(team, fileDownloadUri)
    return ResponseEntity(list, list.status)
}

这是 Angular API 调用

addTeam(team: Team, coverFile: File): Observable<boolean> {
return new Observable<boolean>(subscriber => {
  let formDate = new FormData();
  formDate.append('file', coverFile);
  formDate.append('body', JSON.stringify(team));
  this
    .client
    .post<ResponseWrapper<Boolean>>(environment.BASE_URL + this.ADD_TEAM, formDate, {
      headers: {'Content-Type': 'multipart/form-data'},
     })
......

所以这里我有一个例外说

org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found

所以我发现一些解决方案告诉将角度内容类型设置为 undefined 但这也不起作用 然后我从角度调用中删除了内容类型

但这给了我另一个错误

2020-12-12 19:12:41.298  WARN 16892 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported]

所以我让 spring 应用程序接受 application/octet-stream 但结果,

2020-12-12 19:14:39.775  WARN 16796 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundarykunWjFPmOyVdc8vn' not supported]

那么谁能帮我解决这个问题?

另外,我使用邮递员尝试了这个 API,当我将内容类型设置为 multipart/form-data 时它正在工作

【问题讨论】:

  • 为什么要把它作为FormData formDate.append('body', JSON.stringify(team));的一部分添加?
  • 这部分将team的正文作为json发送,问题是所有东西都在邮递员上工作!但不是有角度的
  • FormData 仅用于文件内容。您不能将另一个 请求正文 附加到它,因此它会失败。
  • 据我所知,您只能从 Angular 发送一个请求正文。这是 http.post 的签名:post(url: string, body: any, options?: RequestOptionsArgs) : Observable&lt;Response&gt;。允许多个标头,但您可以看到不是多个请求正文。
  • 所以这意味着我不能像邮递员那样发送请求?

标签: angular spring spring-boot


【解决方案1】:

在尝试了很多解决方案之后,我终于发现,如果我想以角度发布许多部分,我应该将 json 值的主体作为 json blob 包含它的 type ,并且不需要指定请求本身的内容类型

就这样,

formData.append('body', new Blob([JSON.stringify(team)], {
    type: 'application/json'
  }));

【讨论】:

    【解决方案2】:

    我最近遇到了这个问题,但是在后端使用 NestJS 并将文件名作为第三个参数添加到 append() 函数有帮助。

    formDate.append('file', coverFile, '<FILE_NAME_HERE>');
    

    另外我认为您不需要明确指定“Content-Type”标头,Angular 会自动检测并设置它。

    【讨论】:

      【解决方案3】:

      也许你可以在你的 Angular 应用中试试这个:

      formDate.append('file', coverFile);
      formDate.append('body', new Blob([JSON.stringfy(team)], { type: 'text/plain' }));
      

      现在,在您的 Spring 中,将 team 的类型更改为 string

      @PostMapping("/add", consumes = ["multipart/form-data"])
      fun addTeam(
          @RequestPart(name = "file") file: MultipartFile,
          @RequestPart(name = "body") team: String
      ): ResponseEntity<*> {
      

      现在,在你得到bodyresult 之后,你可以用你的spring 将它解析成一个对象。

      【讨论】:

        猜你喜欢
        • 2016-05-22
        • 1970-01-01
        • 1970-01-01
        • 2021-10-08
        • 1970-01-01
        • 2011-01-02
        • 2016-11-11
        • 2014-05-10
        • 2019-01-17
        相关资源
        最近更新 更多