【发布时间】:2016-09-02 15:16:30
【问题描述】:
我在下载彩信中提供的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
第一个 url -> 第二个 url -> 上面的 url ;所以,总共 2 个重定向
如果我用新的 url 尝试上面发布的 sn-p,它就可以工作。我敢肯定,由于多次重定向,sn-p 一开始就不起作用。
一直在使用 scala 的 play framework,我可以获取任何源示例来下载文件。任何帮助或指针表示赞赏。尝试了各种示例,但仍然无法解决问题。
一些发现 => 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)
}
}
这是我迄今为止一直使用的方法(有效),如 play docs 中所述。但我需要一个同步方法,这意味着我需要执行另一个步骤 成功下载文件。抱歉,没有提前澄清。
更新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
}
}
谢谢,
【问题讨论】:
标签: scala playframework playframework-2.0 twilio