使用媒体 URI 从 twilio 下载媒体文件
Download media file from twilio, using the media URI
我在下载彩信中提供的 media from the media uri 时遇到了问题。
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
1st url -> 2nd url -> above url ;so,all in all 2 redirects
如果我用新的 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)
}
}
这是我到目前为止一直使用的方法(有效),如播放文档中所述。但是我需要一个同步方法,这意味着我需要执行另一个步骤 成功下载文件 .抱歉,没有提前说清楚。
更新 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 客户端跟随重定向应该非常简单,使用 documented option 到客户端:
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]
. If you're on the current cutting-edge and using Play 2.5.x, bodyAsBytes
gives you an Akka ByteString
有很多不错的功能方法,但如果您只想存储数据,您可能只想调用 toArray
:
ws.url(url).withFollowRedirects(true).get().map { response =>
val theBytes:Array[Byte] = response.bodyAsBytes.toArray // Play 2.5
// ... save it
}
我在下载彩信中提供的 media from the media uri 时遇到了问题。
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
1st url -> 2nd url -> above url ;so,all in all 2 redirects
如果我用新的 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)
}
}
这是我到目前为止一直使用的方法(有效),如播放文档中所述。但是我需要一个同步方法,这意味着我需要执行另一个步骤 成功下载文件 .抱歉,没有提前说清楚。
更新 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 客户端跟随重定向应该非常简单,使用 documented option 到客户端:
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]
. If you're on the current cutting-edge and using Play 2.5.x, bodyAsBytes
gives you an Akka ByteString
有很多不错的功能方法,但如果您只想存储数据,您可能只想调用 toArray
:
ws.url(url).withFollowRedirects(true).get().map { response =>
val theBytes:Array[Byte] = response.bodyAsBytes.toArray // Play 2.5
// ... save it
}