我想使用 Play2 来实现一个接收文件 POST 的服务器,在收到文件时对其进行处理,然后在 POST 仍在传输文件时将结果发送给另一个用户的 GET 请求。Play2可以做到这一点吗?我已经使用 Play2 对用户进行身份验证,所以我想使用 Play2 来处理此交易的身份验证。我使用 Java,但如果需要,我可以使用 Scala。如果是这样,我应该调查什么?如果没有,我想我需要研究一些 Java NIO 框架并实现另一个服务器。
问问题
445 次
1 回答
1
我认为这在 Java 中是不可能的,但我已经设法组合了一个简单的 Scala 版本。您仍然可以将 Java 用于项目的所有其他部分。
但请注意,这只是一个粗略的演示,专注于“同时上传和下载”部分,而忽略了其他所有内容。我什至不确定这是不是正确的方法,但它似乎有效。
基本上,您要做的是使用Concurrent.broadcast
创建输入/输出流对。输出部分 ( Enumeratee
) 被流式传输到客户端。然后,您需要一个自定义PartHandler
来接收上传的数据,并将其输入到输入部分 ( Concurrent.Channel
)。
请注意,为了使本示例正常工作,您必须先转到下载页面,然后开始上传文件。
示例 Application.scala
package controllers
import play.api._
import libs.iteratee.{Enumerator, Input, Iteratee, Concurrent}
import play.api.mvc._
import scala.collection.concurrent
object Application extends Controller {
val streams = new concurrent.TrieMap[String,(Enumerator[Array[Byte]], Concurrent.Channel[Array[Byte]])]
def index = Action {
Ok(views.html.index())
}
def download(id: String) = Action {
val (fileStream, fileInput) = Concurrent.broadcast[Array[Byte]]
streams += id -> (fileStream, fileInput)
Ok.stream {
fileStream.onDoneEnumerating(streams -= id)
}
}
def upload = Action(parse.multipartFormData(myPartHandler)) {
request => Ok("banana!")
}
def myPartHandler: BodyParsers.parse.Multipart.PartHandler[MultipartFormData.FilePart[Result]] = {
parse.Multipart.handleFilePart {
case parse.Multipart.FileInfo(partName, filename, contentType) =>
val (thisStream, thisInput) = streams(partName)
Iteratee.fold[Array[Byte], Concurrent.Channel[Array[Byte]]](thisInput) { (inp, data) =>
inp.push(data)
inp
}.mapDone { inp =>
inp.push(Input.EOF)
Ok("upload Done")
}
}
}
}
示例 index.scala.html
<p>
<a href="@routes.Application.download("123456")">Download</a>
</p>
<form action="@routes.Application.upload" method="post" enctype="multipart/form-data">
<input type="file" name="123456">
<input type="submit">
</form>
于 2013-02-06T20:17:37.947 回答