2013-04-04 5 views
4

Получение Gzip-ответа от API, но Dispatch 0.9.5 не имеет методов для декодирования ответа. Есть идеи?Декодировать потоковый ответ GZIP при отправке Scala?

Вот моя текущая реализация, println10 выводит только строковые представления байтов.

Http(
     host("stream.gnip.com") 
     .secure 
     .addHeader("Accept-Encoding", "gzip") 
    /gnipUrl 
     > as.stream.Lines(println))() 

Попытался реализовать собственный обработчик, но не уверен, с чего начать. Вот соответствующий файл для Lines: https://github.com/dispatch/reboot/blob/master/core/src/main/scala/as/stream/lines.scala

Спасибо!

+0

Я вижу, вы открыли на вопрос об этом по адресу https://github.com/dispatch/reboot/issues/52 –

ответ

2

Просто заброшенный Отправка и использовать Java API, непосредственно. Разочаровался, но он выполнил свою работу.

val GNIP_URL = isDev match { 
    case true => "https://url/apath/track/dev.json" 
    case false => "https://url/path/track/prod.json" 
    } 
    val GNIP_CHARSET = "UTF-8" 

    override def preStart() = { 
    log.info("[tracker] Starting new Twitter PowerTrack connection to %s" format GNIP_URL) 

    val connection = getConnection(GNIP_URL, GNIP_USER, GNIP_PASSWORD) 
    val inputStream = connection.getInputStream() 
    val reader = new BufferedReader(new InputStreamReader(new StreamingGZIPInputStream(inputStream), GNIP_CHARSET)) 
    var line = reader.readLine() 
    while(line != null){ 
     println(line) 
     line = reader.readLine() 
    } 
    } 

    private def getConnection(urlString: String, user: String, password: String): HttpURLConnection = { 
    val url = new URL(urlString) 

    val connection = url.openConnection().asInstanceOf[HttpURLConnection] 
    connection.setReadTimeout(1000 * 60 * 60) 
    connection.setConnectTimeout(1000 * 10) 

    connection.setRequestProperty("Authorization", createAuthHeader(user, password)); 
    connection.setRequestProperty("Accept-Encoding", "gzip") 
    connection 
    } 

    private def createAuthHeader(username: String, password: String) = { 
    val encoder = new BASE64Encoder() 
    val authToken = username+":"+password 
    "Basic "+encoder.encode(authToken.getBytes()) 
    } 

Б Пример ГСИО в: https://github.com/gnip/support/blob/master/Premium%20Stream%20Connection/Java/StreamingConnection.java

+0

спрей может удовлетворить ваши потребности. Пример Gzip на этой странице http://spray.io/documentation/spray- клиент/# спрей-клиент. – Carnell

+0

интересно, похоже, мне нужно будет внедрить необработанного клиента, поскольку клиент высокого уровня «пока не поддерживает потоковое HTTP», тем не менее, может быть большой помощью :) – crockpotveggies

-1
+0

Я тоже так думал, но это действительно справедливо только в диспетчерской '0.8' не' 0.9'. Если вы проверите пакет, он был переименован в 'dispatch.classic'. :( – crockpotveggies

+0

ps вот новый файл обработчиков: https://github.com/dispatch/reboot/blob/master/core/src/main/scala/handlers.scala – crockpotveggies

+0

А я пропустил это. Что вы получаете, когда пытаетесь as.string? Возможно, проблема обращения с типом не имеет значения. Похоже, кто-то еще пытается найти ответ на форумах. https://groups.google.com/forum/#!searchin/dispatch-scala/gzip/dispatch-scala/xesmA7NasCM/dEFq04fdfVwJ – Carnell

2

Это не столько решение, как обходной путь, но я в конечном итоге прибегать к минуя -На вещи Future и делать:

val stream = Http(req OK as.Response(_.getResponseBodyAsStream)).apply val result = JsonParser.parse( new java.io.InputStreamReader( new java.util.zip.GZIPInputStream(stream)))

Здесь я использую JsonParser, потому что в моем случае данные, которые я получаю, являются JSON; замените что-то еще в вашем случае использования, если это необходимо.

+0

Интересное обходное решение, простой, и я дам этот снимок :) – crockpotveggies

2

Мое решение только определенный синтаксический анализатор отклика, а также приняла json4s парсер:

object GzipJson extends (Response => JValue) { 
     def apply(r: Response) = { 
     if(r.getHeader("content-encoding")!=null && r.getHeader("content-encoding").equals("gzip")){ 
      (parse(new GZIPInputStream(r.getResponseBodyAsStream), true)) 
     }else 
      (dispatch.as.String andThen (s => parse(StringInput(s), true)))(r) 
     } 
    } 

Так что я могу использовать его, чтобы извлечь ответ Gzip JSon как следующий код:

import GzipJson._ 

    Http(req OK GzipJson).apply 
Смежные вопросы