【发布时间】:2022-01-31 21:14:30
【问题描述】:
我正在使用 Scala Play Framework 以多部分表单数据的形式向客户端发送图像,作为对获取请求的响应。
我以BufferedImage 格式存储图像。目前,我使用getResult 方法将图像发送回客户端:
@Singleton
class ResultController @Inject()(val controllerComponents: ControllerComponents) extends BaseController with DefaultWriteables{
class ResultForm(seq: Seq[BufferedImage]){
val (leftRotation, rightRotation, backRotation) = seq.zip(
Seq("left", "right", "back")
).map{ case (bufferedImage: BufferedImage, partName: String) =>
val bos = new ByteArrayOutputStream()
ImageIO.write(bufferedImage, "png", bos)
MultipartFormData.FilePart(
partName,
s"${partName}_result.png",
Some("image/png"),
ByteString.fromArray(bos.toByteArray())
)
} match {
case Seq(l, r, b) => (l, r, b)
}
def getResponse() = {
MultipartFormData(
dataParts = Map[String, Seq[String]](),
files = Seq(leftRotation, rightRotation, backRotation),
badParts =Seq()
)
}
}
implicit def writeableOf_MultipartFormDataWithBs(
codec: Codec,
contentType: Option[String]
):play.api.http.Writeable[MultipartFormData[akka.util.ByteString]] = {
writeableOf_MultipartFormData(
codec,
Writeable[MultipartFormData.FilePart[akka.util.ByteString]](
(bs: MultipartFormData.FilePart[akka.util.ByteString]) => bs.ref,
contentType
)
)
}
def getResult(accessKey: String) = Action{request =>
val jobResult = GeneratorData.getJobResult(accessKey)
jobResult match {
case Some(files) => {
val rf = new ResultForm(files)
Ok(
rf.getResponse()
)(
writeableOf_MultipartFormDataWithBs(
Codec.iso_8859_1,
contentType = Some("multipart/form-data")
)
)
}
case None => BadRequest(Json.toJson(
new ErrorResponse("The result was not found on the server")
))
}
}
}
但是,在客户端 javascript 中,Response.formData() 仅适用于 chrome 和 opera,但 firefox 会抛出 TypeError: Could not parse content as FormData. 异常。这可能是由于正在进行的图像格式的一些疯狂转换,以及自定义编写器的定义。
如果不是 akka ByteString 我只是传递了一个 TemporaryFile ,那么整个事情会容易得多, documentation 没有列出任何像“create”这样的方法。
有一个 TemporaryFileCreator 特征,但它的子类似乎都没有从任何类型的内存文件转换为 TemporaryFile 的方法。但是,它们确实有指定文件路径的方法,但我只需要使用 RAM 来提供文件。
那么,有没有办法从内存中的文件数据创建一个 TemporaryFile?或者也许是一种将三个图像作为多部分发送的方法,以便 Firefox,而不仅仅是 Opera 和 chromium 可以解析结果? Base64 也是一种解决方案,但我更愿意以“正确”的方式做到这一点。
【问题讨论】:
标签: javascript scala firefox playframework multipartform-data