2011-05-19 46 views
0

凌乱,复杂的问题,但在这里。我正在与Google Checkout进行整合项目,还有一项Google Checkout GWT服务,它返回Checkout网络界面用于将美元兑换成当地货币的货币兑换率。此端点在https://market.android.com/publish/gwt/托管,并在萤火虫我看到这个要去服务器盯着:提取GWT服务的结果

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类在番石榴图书馆(在http://code.google.com/p/guava-libraries/)。我正在寻找的是:

  1. 我找不到任何地方的com.google.common.money.SimpleMoneycom.google.common.money.CurrencyCode类:没有人见过他们吗?
  2. GWT线格式似乎是一个奇怪的JSON字符串。我看到Google Groups消息的各种引用都在讨论有关连线格式的描述,但无法找到潜在的消息或任何能够让我反转的连贯引用:任何人都可以轻松参考?如果我至少能够理解编码是什么,那么如果没有上述问题1中的类文件,我可能会离开。
  3. 我开始漫游Android Market api库http://code.google.com/p/android-market-api/,他们认为他们必须完成一些Android Market通信集成,并且他们似乎已经使用protobufs完成了这项工作。 GWT/protobufs通信位有没有像样的参考?

这种疯狂的根本原因是我需要能够从Google Checkout中获取定期汇率值,因此当我以外币进口销售交易时,我可以按照当时的流行汇率进行转换交易时间。目前的Checkout报告格式不提供此功能,所以大多数人最终会使用与Google使用的不相符的替代汇率来源。这显然是Google Checkout集成界面的一个缺点,但如果我们开始使用Google Checkout界面的缺点,我们将在这里整整一周。我的意图是轮询Checkout界面,查看新履行的订单,然后请求适当的汇率表,以便我可以近乎实时地计算出收款是什么。我已经得到了投票,但不能完全超过汇率。

回答

0

你在看什么是GWT-RPC序列化格式。不幸的是它没有公开记录。幸运的GWT是开源的,所以你可以看源代码,看看它是如何产生的。

注意:这种格式可能会在GWT版本之间改变(我知道它在2.2版本中)。这也是Google不记录它的最有可能的原因 - 如果他们这样做了,他们需要保持向后兼容。

  1. 您看到的类名是Google Checkout内部使用的Java类。当GWT被编译成JS时,名称会被破坏,所以你不会再看到它们。
  2. 如上所述,这是GWT-RPC。
  3. 你想要做的是对Google内部API进行逆向工程。我不会那样做,因为,a。它可能会改变,恕不另行通知,打破你的应用程序,并b。我确信Goog不会喜欢它,它可能违反了服务协议(你读过它了吗?)。
+0

嗯。没有希望。它是一个只提供信息的面向用户的API,我将它与他们现有的接口一起明确地使用它,但我会去寻找服务协议,看看它是否有反对意见。我真的很喜欢它,如果我不必做任何这些废话,但自2011年3月以来,我(和其他人)一直在努力解决这个集成问题,并且考虑到Google Checkout路线图的不透明性,我将继续努力并尝试制作一些进展。 – Femi 2011-05-19 19:10:31

+0

是的我看到人们一直在讨论这一点:http://www.google.com/support/forum/p/checkout-merchants/thread?tid=0e75cc0a1868bbad&hl=zh-CN – 2011-05-19 19:28:58

1

在尝试创建脚本以批量上传应用内产品(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. - 协议版本
  2. - 旗帜。 是FLAG_ELIDE_TYPE_NAMES,是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. - https://market.android.com/publish/gwt/ - 基URL
    2. - FCCA4108CB89BFC2FEC78BA7363D4AF6 - 一些散列,在GWT源文件中引用为serializationPolicyStrongName
    3. - com.google.wireless.android.vending.developer.shared.MerchantService - 服务名
    4. - getCurrencyExchangeRates - 方法名称
    5. - 参数计数。参数类型如下:
      1. - com.google.common.money.CurrencyCode/112449834
      2. - java.util.ArrayList/4159755760
    6. 序列化参数。每个对象都由它的类名和序列化字段列表表示,或者通过对先前遇到的对象的负整数反向引用来表示。在我们的情况下,我们有两个对象:
      1. - com.google.common.money.CurrencyCode/112449834,其中仅具有一个整数字段:
      2. - java.util.ArrayList/4159755760,其具有一个整数长度字段,随后13序列化的列表项。需要注意的是其中12个是序列化,就像上面的一个CurrencyCode对象,最后一个是反向引用(-1)改为(去)序列化这一要求,即CurrencyCode(235)
    7. 我们遇到的第一个对象

应答格式

//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. - 协议版本
  2. - 标志,相同请求
  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个序列化对象 - com.google.common.money.SimpleMoney/627983206。每个SimpleMoney对象有两个字段,例如:
    1. 'Dlfg' - 长整型字段编码为base64数字。这种特殊的一个是
    2. 3,18 - 与整场CurrencyCode对象
0

我在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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$" 
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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$" 
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 

希望你解决这个问题。顺便说一句,有谁知道什么负数意味着什么?