是否有任何函数或方法可以解决 PlayFramework 中的 RequestContext,其工作原理与 Pekko 的 extractRequestContext 类似?
我正在将旧的 Akka Rest API 迁移到 Play3.0,并且我需要移植此 Endpoint 才能播放。幸运的是,Pekko 有完全相同的函数“extractRequestContext”,以及我需要的相同类型:StrictForm.FileData
我想要访问请求上下文的原因是因为这个 API 使用的库需要文件专门为 StrictForm.FileData 类型,所以使用普通的 request.body.file("icon") 并不是真正的选项,除非我可以将这些文件转换为 FileData。
post {
extractRequestContext { _ =>
formFields(
"name".as[String],
"description".as[String].?,
"icon".as[FileData].?,
"color".as[String]
) { (
name: String,
description: Option[String],
icon: Option[FileData],
color: String,
) => {
onboardingController.saveData(
workspaceRequest(userKey, name, description, icon, color)
)
}
}
}
}
我尝试在使用表单时执行此操作,但正如我所说,我找不到转换文件的方法。我知道如果没有文件, getOrElse 会使其失败,这只是为了测试目的。
我找不到任何方法来访问 requestContext 并查看旧的 PlayFramework 文档,我找不到类似的内容
def createWorkspace = Action(parse.multipartFormData) { implicit request =>
request.body.file("icon").map { picture =>
//I wanted to cast the file to StrictForm.FileData, but I did not found a way to do it.
// handle the other form data
workspaceForm.bindFromRequest.fold(
errors =>
println(errors.toString())
BadRequest("Ooops"),
workspaceRequest => {
// this does not work since it returns a Part
// val withPicture = workspaceRequest.copy(icon = Some(picture))
Ok("")
}
)
}.getOrElse(BadRequest("Missing picture."))
}
以下类和方法来自
pekko-http
org.apache.pekko.http.scaladsl.common.StrictForm.FileData
org.apache.pekko.http.scaladsl.server.RequestContext
org.apache.pekko.http.scaladsl.server.Directives.extractRequestContext
如果您使用 pekko-http
作为构建工具,则必须使用以下行将
sbt
添加为项目中的依赖项
libraryDependencies += "org.apache.pekko" %% "pekko-http" % PekkoHttpVersion
我还没有找到可以完成您需要的转换的助手,这意味着您需要自己完成。像这样的东西可以工作
// assuming that the function from the library is like this
def myFunction(fileData: StrictForm.FileData): SomeType = // magic
// the transformer MultipartFormData.FilePart[Files.TemporaryFile] => StrictForm.FileData
def transformTemporaryFilesToFileData(file: MultipartFormData.FilePart[Files.TemporaryFile]): StrictForm.FileData =
StrictForm.FileData(
filename = Option(file.filename),
entity = HttpEntity.Strict(
// file has a `contentType` field but is of type `Option[String]`
// there is a helper class `ContentType` with a `parse` method that could help
// I hardcoded the value just for this example
contentType = ContentTypes.`application/octet-stream`,
data = file.transformRefToBytes()
)
)
// the action to process files could be like this
def form: Action[MultipartFormData[Files.TemporaryFile]] = Action(parse.multipartFormData) { implicit request =>
val filesData = request
.body
.files
.map(transformTemporaryFilesToFileData)
.map(myFunction)
Ok(Json.toJson(filesData))
}