gpt4 book ai didi

scala - Lagom 中的多部分表单数据

转载 作者:行者123 更新时间:2023-12-01 15:22:31 25 4
gpt4 key购买 nike

我想要一个接收项目对象的服务,该对象包含;名称、描述、价格和图片。

  1. 其他属性是字符串,可以很容易地作为 Json 对象发送,但要包含图片,最好的解决方案是什么?
  2. 如果 multipart formdata 是最好的解决方案,它在 Lagom 中是如何处理的?

最佳答案

您可能需要检查 file upload example在 GitHub 上的 lagom-recipes 存储库中。

基本上,这个想法是创建一个额外的 Play 路由器。之后,我们必须按照 reference documentation 中的说明告诉 Lagom 使用它。 (此功能自 1.5.0 起可用)。路由器的外观如下:

class FileUploadRouter(action: DefaultActionBuilder,
parser: PlayBodyParsers,
implicit val exCtx: ExecutionContext) {
private def fileHandler: FilePartHandler[File] = {
case FileInfo(partName, filename, contentType, _) =>
val tempFile = {
val f = new java.io.File("./target/file-upload-data/uploads", UUID.randomUUID().toString).getAbsoluteFile
f.getParentFile.mkdirs()
f
}
val sink: Sink[ByteString, Future[IOResult]] = FileIO.toPath(tempFile.toPath)
val acc: Accumulator[ByteString, IOResult] = Accumulator(sink)
acc.map {
case akka.stream.IOResult(_, _) =>
FilePart(partName, filename, contentType, tempFile)
}

}
val router = Router.from {
case POST(p"/api/files") =>
action(parser.multipartFormData(fileHandler)) { request =>
val files = request.body.files.map(_.ref.getAbsolutePath)
Results.Ok(files.mkString("Uploaded[", ", ", "]"))
}
}
}

然后,我们简单地告诉 Lagom 使用它

  override lazy val lagomServer =
serverFor[FileUploadService](wire[FileUploadServiceImpl])
.additionalRouter(wire[FileUploadRouter].router)

或者,我们可以使用 PlayServiceCall 类。以下是来自 Lightbend 团队的 James Roper 提供的关于如何做到这一点的简单草图:

// The type of the service call is NotUsed because we are handling it out of band
def myServiceCall: ServiceCall[NotUsed, Result] = PlayServiceCall { wrapCall =>
// Create a Play action to handle the request
EssentialAction { requestHeader =>

// Now we create the sink for where we want to stream the request to - eg it could
// go to a file, a database, some other service. The way Play gives you a request
// body is that you need to return a sink from EssentialAction, and when it gets
// that sink, it stream the request body into that sink.
val sink: Sink[ByteString, Future[Done]] = ...

// Play wraps sinks in an abstraction called accumulator, which makes it easy to
// work with the result of handling the sink. An accumulator is like a future, but
// but rather than just being a value that will be available in future, it is a
// value that will be available once you have passed a stream of data into it.
// We wrap the sink in an accumulator here.
val accumulator: Accumulator[ByteString, Done] = Accumulator.forSink(sink)

// Now we have an accumulator, but we need the accumulator to, when it's done,
// produce an HTTP response. Right now, it's just producing akka.Done (or whatever
// your sink materialized to). So we flatMap it, to handle the result.
accumulator.flatMap { done =>

// At this point we create the ServiceCall, the reason we do that here is it means
// we can access the result of the accumulator (in this example, it's just Done so
// not very interesting, but it could be something else).
val wrappedAction = wrapCall(ServiceCall { notUsed =>

// Here is where we can do any of the actual business logic, and generate the
// result that can be returned to Lagom to be serialized like normal

...
})

// Now we invoke the wrapped action, and run it with no body (since we've already
// handled the request body with our sink/accumulator.
wrappedAction(request).run()
}
}
}

一般来说,为此目的使用 Lagom 可能不是一个好主意。如 PlayServiceCall 文档中的 GitHub 问题所述:

Many use cases where we fallback to PlayServiceCall are related to presentation or HTTP-specific use (I18N, file upload, ...) which indicate: coupling of the lagom service to the presentation layer or coupling of the lagom service to the transport.

再次引用 James Roper(几年前)的话:

So currently, multipart/form-data is not supported in Lagom, at least not out of the box. You can drop down to a lower level Play API to handle it, but perhaps it would be better to handle it in a web gateway, where any files handled are uploaded directly to a storage service such as S3, and then a Lagom service might store the meta data associated with it.

您还可以检查 discussion在这里,它提供了更多的见解。

关于scala - Lagom 中的多部分表单数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40347198/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com