You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular向Spring Boot传图片+对象时触发MultipartHttpServletRequest类型错误

问题排查:Angular向Spring Boot传图片+对象触发MultipartHttpServletRequest类型错误

触发的错误

Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]

前端Angular代码

addPostWithIMG(image: File, postRequest: PostRequest): Subscription {
const headers = new HttpHeaders();
headers.append('Content-Type', ' multipart/form-data content');
var file: FormData = new FormData();
file.append('file', image);
file.append('postRequest', JSON.stringify(postRequest));
console.log(file)
return this.http.post<PostRequest>(`${this.baseUrl + "multi"}`, file, {headers: headers}).subscribe({
  next: (data: any) => {
    console.log(data)
  },
  error: (err: any) => {
    console.error(err)
  },
  complete: () => {
    console.log("Done")
  }
});

后端Spring Boot代码

@PostMapping(path = "multi")
public String multi(MultipartHttpServletRequest request) throws IOException {
    String postJSON = request.getParameter("postRequest");
    PostRequest = new Gson().fromJson(post, PostRequest.class);
    MultipartFile file = request.getFile("file");
    Binary files = new Binary(file.getBytes());
    File fileToSave = new File("Post/src/main/resources/" + postRequest.getPostId() + ".png");
    log.info("file: {}", fileToSave.getAbsolutePath());
    if (!fileToSave.exists()) {
        log.info("file created: {}", fileToSave);
        fileToSave.createNewFile();
    } else {
        log.info("file already exist: {}", fileToSave);
    }
    // Try-with-resource
    try (OutputStream out = new FileOutputStream(fileToSave.getAbsolutePath())) {
        out.write(files.getData());
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return "Image saved";
}

问题原因及修复方案

1. 前端Content-Type设置错误

手动设置的Content-Type格式完全错误:

  • 提交FormData时,HttpClient会自动生成包含boundary的multipart/form-data请求头,手动设置会丢失这个关键参数,导致后端无法识别为Multipart请求。
  • 代码中headers.append('Content-Type', ' multipart/form-data content');的字符串格式错误,多了空格和冗余的content后缀。

修复后的前端代码:

addPostWithIMG(image: File, postRequest: PostRequest): Subscription {
  // 移除手动设置的Content-Type,HttpClient会自动处理
  const formData = new FormData();
  formData.append('file', image);
  formData.append('postRequest', JSON.stringify(postRequest));
  
  return this.http.post<PostRequest>(`${this.baseUrl}/multi`, formData).subscribe({
    next: (data: any) => console.log(data),
    error: (err: any) => console.error(err),
    complete: () => console.log("Done")
  });
}

2. 后端代码存在语法错误

原后端代码有两处明显语法问题,会导致编译/运行错误:

  • PostRequest = new Gson().fromJson(post, PostRequest.class);:缺少变量名,且post未定义,应改为PostRequest postRequest = new Gson().fromJson(postJSON, PostRequest.class);
  • 引用postRequest.getPostId()时,变量名之前未正确定义。

修复后的后端代码:

@PostMapping(path = "multi")
public String multi(MultipartHttpServletRequest request) throws IOException {
    String postJSON = request.getParameter("postRequest");
    // 修正变量定义和参数引用
    PostRequest postRequest = new Gson().fromJson(postJSON, PostRequest.class);
    MultipartFile file = request.getFile("file");
    
    if (file == null) {
        return "No file uploaded";
    }
    
    Binary files = new Binary(file.getBytes());
    File fileToSave = new File("Post/src/main/resources/" + postRequest.getPostId() + ".png");
    log.info("file: {}", fileToSave.getAbsolutePath());
    
    if (!fileToSave.exists()) {
        log.info("file created: {}", fileToSave);
        fileToSave.createNewFile();
    } else {
        log.info("file already exist: {}", fileToSave);
    }
    
    try (OutputStream out = new FileOutputStream(fileToSave.getAbsolutePath())) {
        out.write(files.getData());
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
        return "Save failed";
    }

    return "Image saved";
}

3. 可选优化:后端使用更清晰的参数接收方式

可以不用直接依赖MultipartHttpServletRequest,改用@RequestParam注解直接接收参数,代码更易读:

@PostMapping(path = "multi")
public String multi(@RequestParam("file") MultipartFile file,
                    @RequestParam("postRequest") String postJSON) throws IOException {
    PostRequest postRequest = new Gson().fromJson(postJSON, PostRequest.class);
    
    // 后续存储逻辑同上...
    return "Image saved";
}

内容的提问来源于stack exchange,提问作者Sonn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:36:23