2013-03-11 27 views
2

我正在研究Google Cloud端點Web服務,並且在最終獲得身份驗證後,我在生成的代碼中遇到了一些問題。Cloud端點中的@JSONString註釋的非法參數異常生成的代碼

我已經構建了我的ProtoRPC消息,使用Integer字段作爲對象id,client_id和high_water_mark。

class NoteMessage(messages.Message): 
    id = messages.IntegerField(1) 
    client_id = messages.IntegerField(2) 
    high_water_mark = messages.IntegerField(5) 
    ... 

這產生包括在long領域@JsonString屬性Java源代碼,但是當我從服務器的響應,我得到以下錯誤。

E/AndroidRuntime(9231): java.lang.IllegalArgumentException: number type formatted as a JSON number cannot use @JsonString annotation [key id, field private java.lang.Long com.google.api.services.notes.model.NoteApiMessagesNoteMessage.id] 
E/AndroidRuntime(9231): at com.google.common.base.Preconditions.checkArgument(Preconditions.java:119) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:599) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parse(JsonParser.java:350) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:586) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parseArray(JsonParser.java:456) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:549) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parse(JsonParser.java:350) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:586) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonParser.parse(JsonParser.java:289) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:76) 
E/AndroidRuntime(9231): at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:71) 
E/AndroidRuntime(9231): at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:495) 
E/AndroidRuntime(9231): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:465) 
E/AndroidRuntime(9231): at com.ryanharter.hashnote.sync.SyncAdapter.syncNotes(SyncAdapter.java:187) 
E/AndroidRuntime(9231): at com.ryanharter.hashnote.sync.SyncAdapter.onPerformSync(SyncAdapter.java:110) 
E/AndroidRuntime(9231): at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:254) 

我似乎無法找到任何地方,我實際上有超過序列化和反序列化控制,所以這應該是怎樣與Java的工作?

回答

3

正如another post中所述,這是由protorpc庫的一個怪癖造成的。 Google的API客戶端庫期望int64uint64字段在JSON中是字符串,因爲Javascript本身只能處理(由於精度)高達2**53的整數。

正如您在type-format documentation中看到Google的「Discovery」API標準所期待的那樣。但是,protorpc庫不具有相同的語義,並且我們仍然在確定正確的處理方式。

所以,當你使用

id = messages.IntegerField(1) 

您使用的是默認變異爲IntegerField S的是messages.Variant.INT64。這又使得Java客戶端庫期待一個JSON字符串,如

{'id': '123456789'} 

時,而不是響應來自protorpc返回的

{'id': 123456789} 

作爲一個臨時解決您的應用程序,或者使用

id = messages.IntegerField(1, variant=messages.Variant.INT32) 

或者如果您的ID的大小需要超過32位,請使用:

id = messages.StringField(1) 

後腳本:

當你在的話,我建議看Endpoints Proto Datastore API。我們已經完成了一些screencasts的使用。

爲了解決同一個問題與endpoints-proto-datastore,你會導入

from protorpc import messages 
from endpoints_proto_datastore.ndb import EndpointsVariantIntegerProperty 

,並使用

attr1 = EndpointsVariantIntegerProperty(variant=messages.Variant.INT32) 

你的財產。

+1

非常感謝@bossylobster,這正是我所需要的。我發現其他文章解釋了爲什麼會發生,我只是不知道如何解決它。非常感激! – rharter 2013-03-12 21:05:22

+0

優秀的回覆 – 2013-06-24 05:04:21