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

如何使用Akka HTTP处理Multipart POST请求并获取文件字节数组与文件名?

解决Akka HTTP处理Multipart文件上传并获取文件名与字节数组的问题

你的问题出在当前路由把整个Multipart请求体当成纯文本字符串读取了,所以才会拿到包含Content-Disposition头的完整内容。要正确解析文件上传请求,需要用Akka HTTP的Multipart.FormData实体类型来处理,下面是具体的实现方案:

正确的路由实现

import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.Multipart
import akka.stream.scaladsl.Sink
import scala.concurrent.Future
import java.nio.file.Paths
import akka.stream.IOResult

val routePutData = path("api" / "putFile" / Segment) { subDir =>
  entity(as[Multipart.FormData]) { formData =>
    // 遍历表单中的每个part,提取文件信息
    val fileProcessing: Future[(String, Array[Byte])] = formData.parts.mapAsync(1) {
      // 匹配文件类型的part
      case filePart: Multipart.FormData.FilePart =>
        val fileName = filePart.filename.getOrElse("unnamed-file")
        // 将文件流转换为字节数组
        filePart.entity.dataBytes
          .runWith(Sink.fold(Array.empty[Byte])(_ ++ _))
          .map(fileName -> _)
      // 忽略非文件类型的表单字段
      case _ => Future.successful(("non-file-part", Array.empty[Byte]))
    }.runWith(Sink.head) // 假设只上传单个文件,多文件可改用Sink.seq收集

    // 等待文件处理完成,返回结果或执行后续逻辑
    onSuccess(fileProcessing) { case (fileName, fileBytes) =>
      // 这里可以根据subDir参数将文件保存到指定目录,或者处理字节数组
      // 示例:保存文件到磁盘
      // val saveResult: Future[IOResult] = filePart.entity.dataBytes.runWith(FileIO.toPath(Paths.get(subDir, fileName)))
      complete(s"成功接收文件:$fileName,文件大小:${fileBytes.length} 字节")
    }
  }
}

关键细节说明

  • 区分FilePart与普通字段:表单中的文件上传会被解析为Multipart.FormData.FilePart,而普通文本字段是Multipart.FormData.BodyPart,所以我们需要匹配FilePart来提取文件信息。
  • 文件名处理:filePart.filename是Option[String],因为客户端可能未提供文件名,所以用getOrElse设置默认值。
  • 字节数组转换:文件内容以流的形式存在于filePart.entity.dataBytes中,通过Sink.fold可以把流中的字节片段合并成完整的字节数组。如果处理大文件,建议直接用流写入磁盘(示例中注释的FileIO.toPath方式),避免内存溢出。
  • 多文件处理:如果需要支持多文件上传,只需把runWith(Sink.head)改为runWith(Sink.seq),然后处理Future[Seq[(String, Array[Byte])]]即可。

常见误区修正

你之前尝试的formFields指令是用来处理普通的表单文本字段的,并不适用于文件上传场景,所以无法获取文件内容。必须通过遍历formData.parts来识别并处理文件类型的part。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:22:48