Извлечь результаты службы GWT - PullRequest
0 голосов
/ 19 мая 2011

Грязный, сложный вопрос, но здесь идет.Я работаю над проектом интеграции с Google Checkout, и есть служба Google Checkout GWT, которая возвращает курсы обмена валют, используемые веб-интерфейсом Checkout для конвертации долларов США в местные валюты.Эта конечная точка находится в https://market.android.com/publish/gwt/, и смотрит на Firebug. Я вижу, что это происходит на сервере:

7|0|6|https://market.android.com/publish/gwt/|FCCA4108CB89BFC2FEC78BA7363D4AF6|com.google.wireless.android.vending.developer.

shared.MerchantService|getCurrencyExchangeRates|com.google.common.money.CurrencyCode/112449834|java.util.ArrayList/4159755760

|1|2|3|4|2|5|6|5|235|6|13|5|18|5|81|5|53|5|72|5|102|5|121|5|177|5|175|5|205|5|204|5|55|5|86|-1|

, и это возвращается

//OK[235,3,'D0JA',2,86,3,'CXXg',2,55,3,'DW2A',2,204,3,'X9NA',2,205,3,'EuvA',2,175,3,'VIig',2,177,3,'E2Dw',2,121,3,'E4ziA',2,1

02,3,'do$Q',2,72,3,'T82w',2,53,3,'Ds0Q',2,81,3,'Cq5g',2,18,3,'Dlfg',2,13,1,["com.google.common.collect.RegularImmutableList/4

40499227","com.google.common.money.SimpleMoney/627983206","com.google.common.money.CurrencyCode/112449834"],0,7]

Простите за странное форматирование:Я не могу заставить блок кода правильно отформатировать.

Блуждая по сети часами, я смог определить, что класс RegularImmutableList находится в библиотеках Guava (на http://code.google.com/p/guava-libraries/). ЧтоЯ ищу:

  1. Я нигде не могу найти классы com.google.common.money.SimpleMoney или com.google.common.money.CurrencyCode: их кто-нибудь видел?
  2. Формат проводника GWT выглядит какнечетная строка JSON. Я вижу различные ссылки на сообщения групп Google, в которых говорится об описаниях проводного формата, но не могу найти базовые сообщения или какую-либо связную ссылку, которая позволила бы мне изменить это: у кого-нибудь есть ручка для удобной ссылки? Если ямогу хотя бы понять, ЧТО за кодировка, которую я мог бы выбрать без файлов классов из вопроса 1.
  3. Я начал бродить по API-библиотеке Android Market на http://code.google.com/p/android-market-api/, f.Например, они должны были сделать НЕКОТОРЫЕ из интеграции в Android Market, и они, похоже, сделали это, используя protobufs.Есть ли какая-нибудь достойная ссылка на биты связи GWT / protobufs?

Основная причина этого сумасшествия заключается в том, что мне нужно иметь возможность регулярно получать значения обменного курса из Google Checkout, поэтому при импортеВ сделках купли-продажи в иностранной валюте я могу проводить конвертацию по преобладающему курсу на момент совершения сделки.Текущие форматы отчетов Checkout НЕ предоставляют это, поэтому большинство людей используют альтернативные источники обменных курсов, которые не соответствуют тому, что использует Google.Это явно недостаток со стороны интерфейса интеграции Google Checkout, но если мы начнем с недостатков интерфейса Google Checkout, мы будем здесь всю неделю.Мое намерение состоит в том, чтобы опросить интерфейс Checkout для новых выполненных заказов, а затем запросить соответствующую таблицу обменных курсов, чтобы я мог почти в реальном времени выяснить, какие входящие платежи есть.Я получил немного опроса, но не могу пройти через бит обменного курса.

Ответы [ 3 ]

1 голос
/ 24 июля 2012

Пытаясь создать сценарий для массовой загрузки продуктов из приложения для моего приложения (загрузка CSV постоянно заканчивалась ошибочными сообщениями об ошибках), мне удалось понять протокол GWT AJAX.

На самом деле все довольно просто, за исключением того, что вам нужно знать структуру всех используемых классов. Или угадайте, как в случае с внутренними классами, используемыми Google. :)

Я буду использовать примеры из вопроса, чтобы подробно объяснить протокол.


Формат запроса

7|0|6|https://market.android.com/publish/gwt/|FCCA4108CB89BFC2FEC78BA7363D4AF6|com.google.wireless.android.vending.developer.shared.MerchantService|getCurrencyExchangeRates|com.google.common.money.CurrencyCode/112449834|java.util.ArrayList/4159755760|1|2|3|4|2|5|6|5|235|6|13|5|18|5|81|5|53|5|72|5|102|5|121|5|177|5|175|5|205|5|204|5|55|5|86|-1|

Запрос представляет собой список токенов, разделенных каналом, со следующим значением:

  1. 7 - версия протокола
  2. 0 - флаги. 1 - FLAG_ELIDE_TYPE_NAMES, 2 - FLAG_RPC_TOKEN_INCLUDED
  3. 6 - счетчик строк
  4. 6 строковых токенов:
    1. https://market.android.com/publish/gwt/
    2. FCCA4108CB89BFC2FEC78BA7363D4AF6
    3. com.google.wireless.android.vending.developer.shared.MerchantService
    4. getCurrencyExchangeRates
    5. com.google.common.money.CurrencyCode/112449834
    6. java.util.ArrayList/4159755760
  5. Фактический закодированный запрос, который ссылается на строки из приведенного выше списка, используя индексы на основе 1:
    1. 1 - https://market.android.com/publish/gwt/ - базовый URL
    2. 2 - FCCA4108CB89BFC2FEC78BA7363D4AF6 - некоторый хеш, который в источниках GWT ссылается как serializationPolicyStrongName.
    3. 3 - com.google.wireless.android.vending.developer.shared.MerchantService - название услуги
    4. 4 - getCurrencyExchangeRates - название метода
    5. 2 - количество параметров. Типы параметров следующие:
      1. 5 - com.google.common.money.CurrencyCode/112449834
      2. 6 - java.util.ArrayList/4159755760
    6. Сериализованные параметры. Каждый объект представлен либо своим именем класса и списком сериализованных полей, либо обратной отрицательной целой обратной ссылкой на ранее обнаруженный объект. В нашем случае у нас есть два объекта:
      1. 5 - com.google.common.money.CurrencyCode/112449834, который имеет только одно целое поле: 235
      2. 6 - java.util.ArrayList/4159755760, который имеет одно поле целой длины 13 , за которым следуют 13 элементов сериализованного списка. Обратите внимание, что 12 из них являются CurrencyCode объектами, сериализованными так же, как и выше, а последний является обратной ссылкой ( -1 ) к самому первому объекту, с которым мы столкнулись при (де) сериализации этого запроса, то есть CurrencyCode(235)

Формат ответа

//OK[235,3,'D0JA',2,86,3,'CXXg',2,55,3,'DW2A',2,204,3,'X9NA',2,205,3,'EuvA',2,175,3,'VIig',2,177,3,'E2Dw',2,121,3,'E4ziA',2,102,3,'do$Q',2,72,3,'T82w',2,53,3,'Ds0Q',2,81,3,'Cq5g',2,18,3,'Dlfg',2,13,1,["com.google.common.collect.RegularImmutableList/440499227","com.google.common.money.SimpleMoney/627983206","com.google.common.money.CurrencyCode/112449834"],0,7]

Ответ очень похож по формату на запрос, за исключением того, что это массив в формате JS (но не JSON, поскольку он использует недопустимые одинарные кавычки), а в обратном порядке . Значение поля следующее:

  1. 7 - версия протокола
  2. 0 - флаги такие же, как для запроса
  3. Массив строковых токенов:
    1. com.google.common.collect.RegularImmutableList/440499227
    2. com.google.common.money.SimpleMoney/627983206
    3. com.google.common.money.CurrencyCode/112449834
  4. И затем идет один сериализованный объект типа 1 - com.google.common.collect.RegularImmutableList/440499227 с одним полем целочисленной длины 13 , за которым следуют 13 сериализованных объектов класса 2 - com.google.common.money.SimpleMoney/627983206. Каждый объект SimpleMoney имеет два поля, например:
    1. 'Dlfg' - длинное целое поле, закодированное как число base64. Этот конкретный 940000
    2. 3, 18 - CurrencyCode объект с целочисленным полем 18
0 голосов
/ 23 февраля 2016

У меня есть некоторый код, созданный на VB, который может быть полезен для вас, чтобы понять, как анализировать сериализованные строки GWT. «Datos» содержит полученную вами строку.

aAux = Split(Datos, ",[")
aAux(1) = Replace(aAux(1), "],0,7]", "")
aAux(0) = Replace(aAux(0), "//OK[", "")
aAux(0) = Replace(aAux(0), "'", "")

aDescripcion = Split(aAux(1), """,""")
aValor = Split(aAux(0), ",")
InvertirArray aValor

For X = 0 To UBound(aValor)
    If Not IsNumeric(aValor(X)) Then
        Exit For
    End If
    If adescripcion(Int(aValor(X))-1) = "gov.senasa.embalajemadera.shared.domain.Pais/3238585366" Then  
        For Y = X + 1 To UBound(aValor)
            If Int(aValor(Y)) = "" Then '- Do what you want 
            end if
            If adescripcion(Int(aValor(Y))) = "java.lang.Integer/3438268394" Then 
        '- Do what you want
        Next Y
    End If
Next X

Конечно, вы должны адаптировать его к вашим потребностям, и вам придется немного поиграть с массивами ...

InvertirArray:

Public Sub InvertirArray(ByRef Arr() As String)
'- el array va tiene que empezar en 0
Dim X As Long
Dim Hasta As Long
Dim Tmp As String

If UBound(Arr) Mod 2 = 0 Then
   '- Es impar
    Hasta = UBound(Arr) + 1
Else
    Hasta = UBound(Arr)
End If

For X = LBound(Arr) To UBound(Arr) \ 2
    Tmp = Arr(X)
    Arr(X) = Arr(UBound(Arr) - X)
    Arr(UBound(Arr) - X) = Tmp
Next X
end sub

И, конечно, вам нужно декодировать и кодировать длинные числа и даты. Итак:

Public Function EncodeDateGwt(Numero As Double, Optional isDate As Boolean = False) As String

 Dim s As String
Dim a As Double
Dim i As Integer
Dim u As Integer
Dim Base As String
Numero = IIf(isDate, Numero * 1000, Numero)
Base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$"
Do While Val(Numero) <> 0
    a = Numero
    i = 0
    Do While a >= 64
        i = i + 1
        a = a / 64
    Loop
    If i <> u - 1 And u <> 0 Then EncodeDateGwt = EncodeDateGwt & String(u - i - 1, Left(Base, 1))
    a = Int(a)
    EncodeDateGwt = EncodeDateGwt + Mid(Base, a + 1, 1)
    Numero = Numero - a * (64 ^ i)
    u = i
Loop
EncodeDateGwt = EncodeDateGwt & String(i, Left(Base, 1))
End Function

Public Function DecodeDateGwt(Texto As String, Optional isDate As Boolean = False) As Long

Dim Base As String
Dim a As Integer
Base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$"
For a = 1 To Len(Texto)
    DecodeDateGwt = DecodeDateGwt + (InStr(Base, Mid(Texto, a, 1)) - 1) *     (Len(Base) ^ ((Len(Texto) - (a))))
Next
DecodeDateGwt = IIf(isDate, DecodeDateGwt / 1000, DecodeDateGwt)
'devuelve timestamp
End Function

Если то, что вам нужно для кодирования / декодирования, это дата, то вам нужно сделать это раньше:

    Call encodegwtdate(date2unix("20/02/2016"),true)



Public Function Date2Unix(ByVal vDate As Date) As Long
Date2Unix = DateDiff("s", Unix1970, vDate)
End Function

Public Function Unix2Date(vUnixDate As Long) As Date
Unix2Date = DateAdd("s", vUnixDate, Unix1970)
End Function

Надеюсь, вы решите это. Кстати, кто-нибудь знает, что означают отрицательные числа ?????

0 голосов
/ 19 мая 2011

Что вы смотрите, так это формат сериализации GWT-RPC. К сожалению, это не является публично задокументированным. К счастью, GWT имеет открытый исходный код, поэтому вы можете посмотреть на источник, чтобы увидеть, как он создается.

Примечание. Этот формат может меняться в зависимости от версии GWT (я знал, что это произошло в версии 2.2). Это, скорее всего, также причина, по которой Google не документирует это - если бы они это сделали, им нужно было бы обеспечить обратную совместимость.

  1. Имена классов, которые вы видите, являются классами Java, которые Google Checkout использует для внутреннего использования. Когда GWT компилируется в JS, имена искажаются, поэтому вы их больше не видите.
  2. Как уже отмечалось, это GWT-RPC.
  3. Что вы пытаетесь сделать, так это перепроектировать внутренние API Google. Я бы не стал этого делать, потому что Это может измениться без уведомления, сломав ваше приложение и, б. Я уверен, что Гугу это не понравится, и это, вероятно, нарушает соглашение об обслуживании (вы это читали?).
...