似乎用scala play ws框架用body> 10K进行POST是不可能的

时间:2014-08-21 17:19:40

标签: scala http post playframework

似乎无法使用body> 10K

进行POST

如果我这样做:

WS.url(url).post("content more than 10K")

我的身体被剪掉了。正好10K。 我该如何避免这种限制?

1 个答案:

答案 0 :(得分:0)

通常的方法是通过流POST(或PUT)大型文档。这曾经比它应该更难,但如果你愿意使用Play 2.3它已经有所改进。查看What's new?页面上的“播放WS”部分。底层的AsyncHttpClient可能就是你所需要的 - Play用来不让你知道它,甚至现在你需要在将对象拉出WS之后使用另一个库(Dispatch)。

基本上,如上面的文档所示,您实例化一个NingWSClient,使用.underlying拉出AsyncHttpClient,然后对其进行异步调用以发布您的流。这两个历史线程中的第二个为您提供了更多提示,但是弄清楚如何在AsyncHttpClient上进行相关调用本身会很有趣。我会看看今晚是否可以弄清楚,但我认为这对你现在可能有用。

Play WS (2.2.1): post/put large request - 接受的答案显示了如何获得底层HTTP客户端。第二个答案预示着上面的Play 2.3功能。

Simple and concise HTTP client library for Scala - 接受的答案是关于Dispatch,它是Ning的异步HTTP客户端的Scala包装器,这是第一个线程接受的答案所指的。

我必须说Dispatch doc值得称赞。除非有人为你的问题提出一个简单的解决方案,或者如果你需要大量发布大文档,我真的推荐2.3路由和Dispatch。

编辑:以下是一个如何在不使用WS API的情况下执行此操作的示例,但直接使用Ning客户端。我使用了Play 2.4.0-M1中play-ws库附带的Ning软件包,因为它是我方便的。您可以单独获取Ning库并坚持使用您正在使用的任何Play版本。这是根据a streaming GET example I found

改编的
import scala.concurrent.Promise
import com.ning.http.client._
import com.ning.http.client.Response
import com.ning.http.client.AsyncCompletionHandler
import scala.concurrent.ExecutionContext.Implicits.global
import java.io.ByteArrayInputStream

object AsyncWS {
  def main(args: Array[String]): Unit = {
    val config = new AsyncHttpClientConfig.Builder()
    val client = new AsyncHttpClient(config.build())

    // this will send back your request including the body
    val url = "http://httpbin.org/post"

    // testing the basic approach by still reading from a string -- this
    // should work if you can fir your text into a string, otherwise
    // you'll need to write some stream magic
    val testInputStream = 
      new ByteArrayInputStream("s short test string".getBytes)

    val requestBuilder = client.preparePost(url)
    requestBuilder.setBody(testInputStream)

    val request = requestBuilder.build()
    var result = Promise[Int]()
    client.executeRequest(request, new AsyncCompletionHandler[Response]() {
      override def onCompleted(response: Response) = {
        println("got an answer")
        val is  = response.getResponseBodyAsStream()
        val in = scala.io.Source.fromInputStream(is)
        in.getLines().foreach(println(_))
        in.close()
        result.success(response.getStatusCode())
        response
      }

      override def onThrowable(t: Throwable) {
        result.failure(t)
      }
    })
    val getFuture = result.future

    getFuture.map { status =>
      println("result status = " + status)
    }.recover {
      case e: Throwable => {
        println("error e = " + e)
      }
    }
  }
}