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

咨询Spring Boot应用间文件上传通信方案:AngularApp传文件至batchApp

当然可以用REST API实现这个跨应用的文件传递!这是最贴合Spring Boot生态的方案,我给你分两种场景拆解具体实现步骤:

方案一:直接转发MultipartFile(适合小文件)

这种方式是把AngularApp收到的MultipartFile直接通过REST请求转发给batchApp,逻辑简单直接。

步骤1:在batchApp中编写文件接收接口

先给batchApp添加一个接收文件的POST接口,用来接收AngularApp转发过来的文件:

@RestController
@RequestMapping("/batch")
public class BatchFileController {

    @PostMapping("/upload")
    // 允许AngularApp跨域访问,根据实际情况调整origins参数
    @CrossOrigin(origins = "http://localhost:8870")
    public ResponseEntity<String> receiveFile(@RequestParam("file") MultipartFile file) {
        // 这里可以根据需求处理文件:保存到本地目录/直接传入批处理任务
        try {
            Files.copy(file.getInputStream(), 
                       Paths.get("batch-upload-dir", file.getOriginalFilename()),
                       StandardCopyOption.REPLACE_EXISTING);
            return ResponseEntity.ok("文件已成功接收:" + file.getOriginalFilename());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("接收文件失败:" + e.getMessage());
        }
    }
}

步骤2:在AngularApp中添加调用batchApp的逻辑

AngularApp已经能接收前端文件,现在只需要用Spring的WebClient(Spring 5+推荐的非阻塞客户端)来调用batchApp的接口。

首先在AngularApp中配置WebClient:

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient batchWebClient() {
        return WebClient.builder()
                .baseUrl("http://localhost:8871") // batchApp的基础地址
                .build();
    }
}

然后修改AngularApp的文件上传控制器,在保存本地文件后,转发文件到batchApp:

@RestController
public class AngularFileController {

    private final WebClient batchWebClient;

    // 构造注入WebClient
    public AngularFileController(WebClient batchWebClient) {
        this.batchWebClient = batchWebClient;
    }

    @PostMapping("/post")
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
        // 1. 先执行你已实现的本地保存逻辑
        try {
            Files.copy(file.getInputStream(), 
                       Paths.get("upload-dir", file.getOriginalFilename()),
                       StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("保存文件到本地失败:" + e.getMessage());
        }

        // 2. 转发文件到batchApp
        try {
            String batchResponse = batchWebClient.post()
                    .uri("/batch/upload")
                    .contentType(MediaType.MULTIPART_FORM_DATA)
                    .body(BodyInserters.fromMultipartData("file",
                            new ByteArrayResource(file.getBytes()) {
                                @Override
                                public String getFilename() {
                                    return file.getOriginalFilename(); // 必须指定文件名,否则batchApp无法识别
                                }
                            }))
                    .retrieve()
                    .bodyToMono(String.class)
                    .block(); // 异步场景可去掉block,改用Mono/Flux返回

            return ResponseEntity.ok("文件上传到AngularApp成功,且已转发到batchApp:" + batchResponse);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("转发文件到batchApp失败:" + e.getMessage());
        }
    }
}
方案二:传递文件路径(适合大文件,避免内存占用)

如果文件体积较大,直接转发MultipartFile会占用过多内存,这时候可以让AngularApp保存文件后,把文件路径传给batchApp,由batchApp直接读取文件(前提是两个应用能访问到同一个文件目录,比如共享磁盘、NFS,或者用对象存储如MinIO传递文件URL)。

步骤1:batchApp添加接收文件路径的接口

@RestController
@RequestMapping("/batch")
public class BatchFileController {

    @PostMapping("/upload-by-path")
    @CrossOrigin(origins = "http://localhost:8870")
    public ResponseEntity<String> receiveFileByPath(@RequestParam("filePath") String filePath) {
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            return ResponseEntity.badRequest().body("文件不存在:" + filePath);
        }

        // 读取文件并处理批任务
        try {
            Files.copy(targetFile.toPath(), 
                       Paths.get("batch-upload-dir", targetFile.getName()),
                       StandardCopyOption.REPLACE_EXISTING);
            return ResponseEntity.ok("通过路径读取文件成功:" + targetFile.getName());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("处理文件失败:" + e.getMessage());
        }
    }
}

步骤2:AngularApp修改控制器传递路径

@PostMapping("/post")
public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
    String localFilePath = "upload-dir/" + file.getOriginalFilename();
    
    // 1. 保存文件到本地
    try {
        Files.copy(file.getInputStream(), 
                   Paths.get(localFilePath),
                   StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("保存文件到本地失败:" + e.getMessage());
    }

    // 2. 传递文件路径给batchApp
    try {
        String batchResponse = batchWebClient.post()
                .uri(uriBuilder -> uriBuilder.path("/batch/upload-by-path")
                        .queryParam("filePath", localFilePath)
                        .build())
                .retrieve()
                .bodyToMono(String.class)
                .block();

        return ResponseEntity.ok("文件上传成功,已通知batchApp读取文件:" + batchResponse);
    } catch (Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("通知batchApp失败:" + e.getMessage());
    }
}
关键注意事项
  • 跨域配置:如果两个应用端口不同,必须在batchApp的控制器上添加@CrossOrigin注解,或者全局配置跨域规则,避免请求被浏览器拦截。
  • 文件大小限制:Spring Boot默认限制Multipart文件大小,需要在两个应用的application.properties中配置:
    spring.servlet.multipart.max-file-size=100MB
    spring.servlet.multipart.max-request-size=100MB
    
  • 异步处理:如果批处理任务耗时较长,建议batchApp用@Async或者Spring Batch的JobLauncher异步执行任务,避免AngularApp的请求超时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:16:16