图像在被检索(通过HTTP)时被破坏,然后(通过HTTP)发送到数据库。图像的原始数据以字符串形式处理。
服务为图像文件发送GET,接收原始图像数据(响应的正文)和内容类型的响应。然后,与上述请求的主体和Content-Type头部一起发送PUT请求。 (PUT请求是通过以字符串形式提供主体来构造的)此PUT请求被发送到RESTful数据库(CouchDB),创建attachment(对于那些不熟悉CouchDB的人,附件就像静态文件一样)。 p>
现在我有原始图像,我的服务GETs和PUTs到数据库,以及原始图像的“副本”,我现在可以从数据库中获取。如果我然后`curl --head -v“[copy的url]”它具有原始图像的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:admin@localhost: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 :(得分:1)
转换为String
肯定会导致问题。您需要使用Daniel提到的字节。
查看源代码看起来ws.Response
只是一个包装器。如果你到达基础类,那么有一些方法可以帮助你。在Java方面,有人在GitHub上提交了更多获取响应数据的方法,而不是String
。
我不熟悉scala,但这样的事情可能有用:
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