2013-08-21 38 views
1

图像在被检索(通过HTTP)时被破坏,然后被发送(通过HTTP)到数据库。图像的原始数据以字符串形式处理。如何安全地处理Java中的原始(文件)数据?

该服务发送GET图像文件,接收原始图像数据(响应的正文)和内容类型的响应。然后,通过上述请求的主体和Content-Type头发送PUT请求。 (PUT请求通过在String中提供主体来构造)这个PUT请求被发送到RESTful数据库(CouchDB),创建一个attachment(对于那些不熟悉CouchDB的用户来说,附件就像一个静态文件)。

现在我有原始图像,我的服务GETs和PUTs到数据库,这个原始图像的'复制',我现在可以从数据库中获取。如果我然后`curl --head -v“[复制网址]”它具有原始图像的Content-Type,但Content-Length已更改,从200kb变为约400kb。如果我使用浏览器获取“复制”图像,则不会呈现该图像,而原始呈现效果良好。它已损坏。

可能是什么原因?我的猜测是,虽然将原始数据作为字符串处理,但我的框架猜测编码错误并破坏了它。我无法确认或否认这一点。我怎样才能以安全的方式处理这个原始数据/请求体,或者我如何正确处理编码(如果证明是问题的话)?

详情:Play2 Framework's HTTP client,Scala。下面的测试重现:

"able to copy an image" in { 
    def waitFor[T](future:Future[T]):T = { // to bypass futures 
    Await.result(future, Duration(10000, "millis")) 
    } 
    val originalImageUrl = "http://laughingsquid.com/wp-content/uploads/grumpy-cat.jpg" 
    val couchdbUrl = "http://admin:[email protected]:5984/testdb" 
    val getOriginal:ws.Response = waitFor(WS.url(originalImageUrl).get) 
    getOriginal.status mustEqual 200 
    val rawImage:String = getOriginal.body 
    val originalContentType = getOriginal.header("Content-Type").get 

    // need an empty doc to have something to attach the attachment to 
    val emptyDocUrl = couchdbUrl + "/empty_doc" 
    val putEmptyDoc:ws.Response = waitFor(WS.url(emptyDocUrl).put("{}")) 
    putEmptyDoc.status mustEqual 201 
    //uploading an attachment will require the doc's revision 
    val emptyDocRev = (putEmptyDoc.json \ "rev").as[String] 

    // create actual attachment/static file 
    val attachmentUrl = emptyDocUrl + "/0" 
    val putAttachment:ws.Response = waitFor(WS.url(attachmentUrl) 
    .withHeaders(("If-Match", emptyDocRev), ("Content-Type", originalContentType)) 
    .put(rawImage)) 
    putAttachment.status mustEqual 201 

    // retrieve attachment 
    val getAttachment:ws.Response = waitFor(WS.url(attachmentUrl).get) 
    getAttachment.status mustEqual 200 
    val attachmentContentType = getAttachment.header("Content-Type").get 

    originalContentType mustEqual attachmentContentType 
    val originalAndCopyMatch = getOriginal.body == getAttachment.body 
    originalAndCopyMatch aka "original matches copy" must beTrue // << false 
} 

失败在最后的“必须”:

[error] x able to copy an image 
[error] original matches copy is false (ApplicationSpec.scala:112) 
+0

检索和处理这些数据的格式是'Array [Byte]'。其他类型的序列(“Byte”)也适用,但效率不高。我不会回答,因为我不知道您使用的HTTP客户端。 –

回答

1

String的转换肯定会导致问题。你需要像Daniel提到的那样处理字节。

看看源代码,它看起来像ws.Response只是一个包装。如果你到达底层类,那么有一些方法可以帮助你。在Java方面,有人在GitHub上提交了一个提交除String以外的更多获取响应数据的方法。

我不熟悉斯卡拉但像这样的事情可能工作:

getOriginal.getAHCResponse.getResponseBodyAsBytes 

// instead of getOriginal.body 

WS.scala
https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/libs/ws/WS.scala

WS.java
在这里,您可以看到Response有一些新的方法,getBodyAsStream()asByteArray
https://github.com/playframework/playframework/blob/master/framework/src/play-java/src/main/java/play/libs/WS.java

+0

我的问题的答案是独占地处理原始数据作为字节数组。奇怪的是'asByteArray'方法还没有进入scala版本。 –

相关问题