Can Java NIO be used in Play 2 framework at the same time for POST and GET files?

I would like to use Play2 to implement a server that receives POST of files, processes the files as they are received, and sends the results in a GET request from another user, while the POST is still transferring files. Is it possible to do this with Play2? I am already using Play2 to authenticate users, so I would like to use Play2 to authenticate this transaction. I am using Java, but I can use Scala if needed. If so, what should I be looking at? If not, I think I need to learn some Java NIO platforms and implement a different server.

+3


source to share


1 answer


I don't think it's possible in Java, but I've managed to put together a simple version of Scala. You can still use Java for all other parts of your project.

But keep in mind that this is just a rough demo focusing on "simultaneous upload and download" and ignore everything else. I'm not even sure if this is the correct way to do it, but it seems to work.

Basically what you want to use Concurrent.broadcast

to create a pair of input / output streams. The output part ( Enumeratee

) is passed to the client. Then you need a custom PartHandler

one that takes the loaded data as it comes in and passes it to the input ( Concurrent.Channel

) part .

Please remember that in order for this example to work, you first need to go to the download page , then start downloading the file.



sample 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")
        }
    }
  }
}

      

sample 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>

      

+1


source







All Articles