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

Angular与SpringBoot应用中同时上传文件和对象的实现问题

解决方案

前端调整(保持原有逻辑即可)

你的uploadBoth方法逻辑没问题,若需支持多文件,只需多次调用formData.append('file', file, file.name)即可:

uploadBoth(files: File[], options: EnumerateOptions): Observable<Blob>{
  const formData: FormData = new FormData();
  // 多文件上传:循环添加所有文件
  files.forEach(file => formData.append('file', file, file.name));
  // 将options转为JSON字符串存入FormData
  formData.append('options', JSON.stringify(options));
  
  return this.httpClient.post(this.baseuri + "/test", formData, {responseType: 'blob'});
}

后端处理关键:手动解析JSON字符串

Spring无法自动将FormData中的JSON字符串直接转换为EnumerateOptions实例,需要手动完成解析。具体实现如下:

1. 新增同时接收文件和参数的接口

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@RestController
public class UploadController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class);
    private final ObjectMapper objectMapper;

    // 注入Spring自动配置的ObjectMapper用于JSON解析
    public UploadController(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    // 支持单/多文件 + options参数上传
    @PostMapping("/test")
    public ResponseEntity<String> test(@RequestParam("file") List<MultipartFile> files,
                                      @RequestParam("options") String optionsJson) {
        try {
            // 将JSON字符串转为EnumerateOptions实例
            EnumerateOptions options = objectMapper.readValue(optionsJson, EnumerateOptions.class);
            
            // 处理上传的文件
            for (MultipartFile file : files) {
                LOGGER.info("上传文件名:{}", file.getOriginalFilename());
            }
            
            // 验证options参数解析结果
            LOGGER.info(options.toString());
            LOGGER.info("字体大小:{}", options.getFontSize());
            LOGGER.info("第一个变更值:{}", options.getChanges()[0]);
            
            return ResponseEntity.ok("上传成功");
        } catch (Exception e) {
            LOGGER.error("解析参数失败", e);
            return ResponseEntity.badRequest().body("参数解析错误");
        }
    }
}

2. 确保EnumerateOptions类完整性

Jackson序列化/反序列化需要类具备无参构造函数和完整的getter/setter方法,补充后代码如下:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Arrays;

public class EnumerateOptions {
    @JsonProperty("position")
    private String position;
    @JsonProperty("fontStyle")
    private String fontStyle;
    @JsonProperty("fontSize")
    private String fontSize;
    @JsonProperty("changes")
    private int[] changes;

    // 必须保留无参构造函数
    public EnumerateOptions() {}

    // 完整的getter和setter方法
    public String getPosition() { return position; }
    public void setPosition(String position) { this.position = position; }
    public String getFontStyle() { return fontStyle; }
    public void setFontStyle(String fontStyle) { this.fontStyle = fontStyle; }
    public String getFontSize() { return fontSize; }
    public void setFontSize(String fontSize) { this.fontSize = fontSize; }
    public int[] getChanges() { return changes; }
    public void setChanges(int[] changes) { this.changes = changes; }

    @Override
    public String toString() {
        return "EnumerateOptions{" +
                "position='" + position + '\'' +
                ", fontStyle='" + fontStyle + '\'' +
                ", fontSize='" + fontSize + '\'' +
                ", changes=" + Arrays.toString(changes) +
                '}';
    }
}

常见问题排查

  • 若出现解析失败,可在浏览器开发者工具中查看FormData的options字段,确认JSON字符串格式是否正确。
  • 确保EnumerateOptions的字段key与前端JSON的key完全匹配(@JsonProperty已指定映射关系,无需担心大小写问题)。
  • 单文件上传时,后端参数可改为MultipartFile file,无需使用List。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:20:26