Scala 使用媒体URI从twilio下载媒体文件
我在下载彩信时遇到问题Scala 使用媒体URI从twilio下载媒体文件,scala,playframework,playframework-2.0,twilio,Scala,Playframework,Playframework 2.0,Twilio,我在下载彩信时遇到问题 val url = https://api.twilio.com/2010-04-01/Accounts/xx/Messages/xx/Media/xx 提供的媒体url位于上述结构中 new URL(url) #> new File("file.png") !! //this fails, due to multiple redirects 当我在浏览器中打开URI时,重定向以 http://media.twiliocdn.com.s3-external-1.
val url = https://api.twilio.com/2010-04-01/Accounts/xx/Messages/xx/Media/xx
提供的媒体url位于上述结构中
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
第一个url->第二个url->上面的url;因此,总共有2个重定向
如果我用新的url尝试上面发布的代码片段,它会起作用。我确信这是因为多重重定向,代码片段一开始就不起作用
使用play framework和scala时,我可以得到任何源示例来下载该文件。感谢您的帮助或指点。尝试了各种各样的例子,但仍然无法解决问题
一些发现=>
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)
}
}
正如play文档中所解释的,这是我到目前为止一直使用的方法(有效)。但是我需要一种同步方法,这意味着我需要在成功下载文件时执行另一个步骤。对不起,没有在前面澄清
更新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
}
}
谢谢,我没有使用Twilio MMS API,但是让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及更低版本。如果您使用的是当前最先进的技术,那么它会为您提供一个具有许多优秀功能方法的解决方案,但是如果您只想存储数据,您可能只想调用toArray
:
ws.url(url).withFollowRedirects(true).get().map { response =>
val theBytes:Array[Byte] = response.bodyAsBytes.toArray // Play 2.5
// ... save it
}
谢谢你的回答。但是,我似乎找不到与ws响应相关/适用的
bodyAsBytes
方法。我是否遗漏了任何进口或。。。。使用2.3.8 BTW感谢您的帮助@millhouse!如果您想要Twilio的感谢t恤,请发送电子邮件至mspeir@twilio.com.