我在下载mms消息上提供的media from the media uri时遇到了问题。
val url = https://api.twilio.com/2010-04-01/Accounts/xx/Messages/xx/Media/xx
提供的媒体网址是上述结构,
new URL(url) #> new File("file.png") !! //this fails, due to multiple redirects
当我在浏览器中打开URI时,重定向最终会进入
http://media.twiliocdn.com.s3-external-1.amazonaws.com/xx/xx
第1个网址 - >第二个网址 - >以上网址;所以,所有2个重定向
如果我尝试使用新网址发布上面的代码段,它就可以了。我确信它是因为多重重定向,所以片段首先没有用。
使用播放框架与 scala ,我可以获得任何源代码示例来下载该文件。任何帮助或指示表示赞赏。试过各种例子,但仍无法解决问题。
一些调查结果=> Accessing Twilio MMS images
scala的任何类似内容?
更新: @millhouse
def fileDownloader(urls: String, location: String) = {
import play.api.Play.current
import scala.concurrent.ExecutionContext.Implicits.global
// Make the request
val futureResponse: Future[(WSResponseHeaders, Enumerator[Array[Byte]])] =
WS.url(urls).withFollowRedirects(true).getStream()
futureResponse.flatMap {
case (headers, body) =>
val file = new File(location)
val outputStream = new FileOutputStream(file)
// The iteratee that writes to the output stream
val iteratee = Iteratee.foreach[Array[Byte]] { bytes =>
outputStream.write(bytes)
}
// Feed the body into the iteratee
(body |>>> iteratee).andThen {
case result =>
// Close the output stream whether there was an error or not
outputStream.close()
// Get the result or rethrow the error
result.get
}.map(_ => file)
}
}
这是我一直使用的方法(作品),如播放文档中所述。但我需要同步方法,这意味着我需要在成功下载文件时执行另一步 。对不起,未提前澄清。
更新2:以这种方式解决,
def fileDownloader(urls: String, location: String) = {
import play.api.Play.current
import scala.concurrent.ExecutionContext.Implicits.global
// Make the request
val futureResponse: Future[(WSResponseHeaders, Enumerator[Array[Byte]])] =
WS.url(urls).withFollowRedirects(true).getStream()
val downloadedFile: Future[File] = futureResponse.flatMap {
case (headers, body) =>
val file = new File(location)
val outputStream = new FileOutputStream(file)
// The iteratee that writes to the output stream
val iteratee = Iteratee.foreach[Array[Byte]] { bytes =>
outputStream.write(bytes)
}
// Feed the body into the iteratee
(body |>>> iteratee).andThen {
case result =>
// Close the output stream whether there was an error or not
outputStream.close()
// Get the result or rethrow the error
result.get
}.map(_ => file)
}
downloadedFile.map{ fileIn =>
//things needed to do
}
}
谢谢,
答案 0 :(得分:2)
我没有使用Twilio MMS API,但是使用documented option到客户端,让Play Framework HTTP客户端遵循重定向应该非常简单:
val url = "https://api.twilio.com/2010-04-01/Accounts/xx/Messages/xx/Media/xx"
ws.url(url).withFollowRedirects(true).get().map { response =>
val theBytes:Array[Byte] = response.bodyAsBytes // Play 2.4 and lower
// ... save it
}
请注意,上述代码适用于Play 2.4.x及更低版本; the bodyAsBytes
method of WSResponse
returns an Array[Byte]
。如果您处于当前最前沿并且使用Play 2.5.x, bodyAsBytes
为您提供了Akka ByteString
,其中包含许多不错的功能方法,但您可能只想在其上调用toArray
是存储数据:
ws.url(url).withFollowRedirects(true).get().map { response =>
val theBytes:Array[Byte] = response.bodyAsBytes.toArray // Play 2.5
// ... save it
}