2014-02-17 96 views
0

我有一個問題,我無法從Play框架的文檔中找到足夠的信息。我有一個相當大的JSON,並將此JSON發送到WebSocket端點。我現在需要以某種方式從客戶端壓縮此JSON並將其發送到WebSocket端點。一旦服務器獲得這個壓縮的JSON,它將解壓縮並處理它。目前有什麼方法可以使用任何Play Framework的功能來完成此操作?還是有一個我可以研究的圖書館?Play框架 - Zip JSON請求

我正在使用Play Framework 2.1.1。

這是我做派壓縮的JSON請求到服務器:

val input = Source.fromURL(getClass.getResource("/bulk_json_10000.txt")).mkString 
val bulkJson: Array[Byte] = Utility.zipJson(input) 

只是爲了測試目的,我使用的向服務器發送請求的HTTP庫:

val result = Http.postData(url, bulkJson) 
    .header("Content-Type", "application/json") 
    .header("Charset", "UTF-8") 
    .option(HttpOptions.readTimeout(10000)) 
    .responseCode 
logger.info("The response from the server " + result) 

但我看到的所有內容都是400作爲響應代碼。

添加Content-Encoding頭象下面後:

.header("Content-Encoding", "gzip") 

我能夠擺脫壞請求錯誤的,現在的服務器拋出「從服務器上的文件意外結束」錯誤。

這是我做的控制器:

def gzipTest = Action(parse.anyContent) { request => 
    println(request.body) 
    Ok("Done!") 
    } 

有什麼我失蹤?我甚至沒有試圖在服務器端做任何事情,並提出要求。爲什麼服務器會失敗?

擺弄周圍有GZIPing客戶端上的請求後,我加入了GZipFilter我Global.scala,我有以下錯誤,我看到的是從服務器獲取拋出:

org.jboss.netty。 handler.codec.embedder.CodecEmbedderException:org.jboss.netty.handler.codec.compression.CompressionException:解壓縮失敗(-3):不是org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived()中的gzip流HttpContentDecoder.java:116) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459) at org.jboss.net ty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536) at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435) at org.jboss.netty。 channel.Channels.fireMessageReceived(Channels.java:268) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) at org.jboss.netty.channel.socket.nio.NioWorker.read( NioWorker.java:88) at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:107) at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector。 java:312) at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:88) at org.jboss.netty.channel.socket.nio.NioWorker。運行(NioWorker.java:178) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source) at java.lang.Thread.run(未知來源) 原因:org.jboss.netty.handler.codec.compression。CompressionException:解壓縮失敗(-3):不是gzip流 at org.jboss.netty.handler.codec.compression.ZlibUtil.exception(ZlibUtil.java:31) at org.jboss.netty.handler.codec.compression .ZlibUtil.fail(ZlibUtil.java:27) at org.jboss.netty.handler.codec.compression.ZlibDecoder.decode(ZlibDecoder.java:152) at org.jboss.netty.handler.codec.oneone.OneToOneDecoder .handleUpstream(OneToOneDecoder.java:66) ......在org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:409) 19多個 java.nio.channels.ClosedChannelException 在組織.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:127) at org.jboss.netty.c在org.jboss.netty.channel上的hannel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99) Channels.write(Channels.java:725) at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.doEncode(OneToOneEncoder.java:71) at org.jboss.netty.handler.codec.oneone.OneToOneEncoder。 handleDownstream(OneToOneEncoder.java:59) at org.jboss.netty.channel.Channels.write(Channels.java:704) at org.jboss.netty.channel.Channels.write(Channels.java:671) at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:248) at play.core.server.netty.PlayDefaultUpstreamHandler $$ ano $ 2 $$ anonfun $ handle $ 6 $$ anonfun $ 12.apply(PlayDefaultUpstreamHandler.scala:208) at play.core.server.netty.PlayDefaultUpstreamHandler $$ anon $ 2 $$ anonfun $ handle $ 6 $$ anonfun $ 12.apply(PlayDefaultUpstreamHandler .scala:204) at play.api.libs.iteratee.Enumeratee $$ anon $ 50 $$ anon $ 16 $$ anonfun $ play $ api $ libs $ iteratee $ Enumeratee $$ anon $$ anon $$ step $ 2 $$ anonfun $ apply $ 13.apply(Enumeratee.scala:359) at play.api.libs.iteratee.Enumeratee $$ anon $ 50 $$ anon $ 16 $$ anonfun $ play $ api $ libs $ iteratee $ Enumeratee $$ anon $$ anon $$ step $ 2 $$ anonfun $ apply $ 13.apply(Enumeratee.scala:359) at scala.concurrent.Future $$ anonfun $ map $ 1.liftedTree2 $ 1(Future.scala:253) at scala.concurrent.Future $ $ anonfun $ map $ 1.apply(Future.scala:249) at scala.concurrent.Future $$ anonfun $ map $ 1.apply(Future.scala:249) at scala .concurrent.impl.CallbackRunnable.run(Promise.scala:29) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source) at java .lang.Thread.run(Unknown Source)

+0

在客戶端請求中,嘗試添加頭gzip:'.header(「Content-Encoding」,「gzip」)' –

+0

我這樣做,並遇到以下錯誤:java.net.SocketException:意外結束來自服務器的文件 – sparkr

+0

從錯誤「不是gzip流」看起來像你的方法zipJson沒有壓縮它作爲GZIP,但作爲不同的東西 –

回答

1

Play Framework 2.2.x supports Gzip直接。對於你的版本,你可以看看this related answer。如上所述,如果Play在前端後面,則可以在前端執行gzip/gunzip。

+0

但Play使用Netty服務器,我不能在Netty服務器中配置某些內容以實現壓縮並且減壓? – sparkr

+0

如[Play Issue tracking](https://github.com/playframework/playframework/pull/375)中所述,與Netty集成的支持包含在2.2.x中。 如果你有一個事先2。x版本,你不想更新到最後一個穩定版本,你可以應用他們爲支持它所做的提交更改:[Here](https://github.com/wpraet/Play20/commit/bab79803f2a5d7f8f41177e85eefc95f4087bb1c)。 –

+0

謝謝你。在你引用的Stack Overflow線程中,我看到其中一個用戶提供了一些代碼,它們實際上是將gzip的響應返回給客戶端。我的要求是,我希望這樣做,一旦發送請求發送到服務器時,第二次發送響應到客戶端。如何在將JSON請求發送到服務器時執行此操作?我壓縮了JSON請求,並將其作爲Byte [Array]。我如何在普通的HTTP Post請求中發送這個請求到Play框架服務器?我已經用我迄今所做的工作更新了我的帖子。 – sparkr