在 http4s 中处理多部分内容



我想知道如何使用 http4s 库处理多部分内容。

想象一个具有以下代码片段的服务(完整的要点在这里(:

  case GET -> Root / "form" =>
   Ok(
   """|<html>
      |<body>
      |<form method="post" action="/post" enctype="multipart/form-data">
      | <input type="date" name="birthDate" placeholder="birthDate">
      | <input type="file" name="dataFile">
      | <input type="submit">
      |</form></body></html>""".stripMargin).
      withContentType(Some(`Content-Type`(`text/html`)))
case req @ POST -> Root / "post" => {
 req.decode[Multipart[IO]] { m =>
  Ok(
    s"""Multipart DatanParts:${m.parts.length}
       |${m.parts.map { case f: Part[IO] => { f.name + ", headers: " + f.headers.mkString(",")} }.mkString("n")}""".stripMargin)
}
  }

如果我执行服务并填写相应的字段,我会得到如下所示的输出:

Multipart Data
Parts:2
Some(birthDate), headers: Content-Disposition: form-data; name="birthDate"
Some(dataFile), headers: Content-Disposition: form-data; name="dataFile"; 
 filename="file.pdf",Content-Type: application/pdf

所以我知道如何获取有关零件的信息,这些零件是 Part[IO] 类型的元素,包含headersbody.

我想知道如何处理这些零件。例如,在这种情况下,我想打开文件并告知其长度。这样做的惯用方法是什么?

Part[IO]body是一个可以使用fs2库中的方法进行处理的Stream[F[_],Byte]

有几种可能性,一种可能性是使用 io.file.writeAllio.file.writeAllASync 方法将流内容写入文件。

适用于基于字符串的文件的另一种可能性是使用 utf8Decode 方法处理流的内容。

结果可能是:

  case req @ POST -> Root / "post" => {
    req.decode[Multipart[IO]] { m => {
      m.parts.find(_.name == Some("dataFile")) match {
        case None => BadRequest(s"Not file")
        case Some(part) => for {
          contents <- part.body.through(utf8Decode).runFoldMonoid
          response <- Ok(s"""Multipart DatanParts:${m.parts.length}
                            |File contents: ${contents}""".stripMargin)
        } yield response
      }
    }
   }
  }
 }

前面的代码段将返回文件的内容。

相关内容

  • 没有找到相关文章

最新更新