使用媒体URI

时间:2016-05-07 16:46:55

标签: scala playframework playframework-2.0 twilio

我在下载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
}
                  }

谢谢,

1 个答案:

答案 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  
}