Cloud Endpoints生成的代码中@JSONString注释的非法参数异常

时间:2013-03-11 22:29:20

标签: java python google-cloud-endpoints

我正在开发Google Cloud Endpoint网络服务,在最终让auth工作之后,我对生成的代码遇到了一些问题。

我使用Integer字段为对象id,client_id和high_water_mark构建了这样的ProtoRPC消息。

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

这会生成包含@JsonString字段long属性的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一起使用?

1 个答案:

答案 0 :(得分:3)

another post中所述,这是由protorpc库的怪癖引起的。 Google的API客户端库希望int64uint64字段成为JSON中的字符串,因为Javascript本身只能处理(由于精度)整数2**53

正如您在type-format documentation中看到的Google的“Discovery”API标准,这是对这些类型的期望。但是,protorpc库没有currently use相同的语义,我们仍然在确定正确的继续方法。

所以,当你使用

id = messages.IntegerField(1)

您正在使用IntegerField的默认变体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)

为您的财产。