【问题标题】:Google Cloud Endpoints: NumberFormatException in Android client when response includes DateTime fieldGoogle Cloud Endpoints:当响应包含 DateTime 字段时,Android 客户端中出现 NumberFormatException
【发布时间】:2013-08-05 10:34:42
【问题描述】:

我刚开始使用 Google Cloud Endpoints, 我用 Python 构建了一个 API,甚至可以在 Android Studio/Gradle 环境中使用生成的源代码。

我遇到的问题是,只要来自 Cloud Endpoints 的响应包含 DateTime 对象,就会引发 NumberFormatException。

08-05 13:27:28.143  32116-32141/com.dgt.ds E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
        java.lang.RuntimeException: An error occured while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:299)
        at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
        at java.util.concurrent.FutureTask.run(FutureTask.java:137)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
        at java.lang.Thread.run(Thread.java:856)
        Caused by: java.lang.IllegalArgumentException:  [key created_at, field private com.google.api.client.util.DateTime com.google.api.services.dsApi.model.ServicesDResponse.createdAt]
        at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:797)
        at com.google.api.client.json.JsonParser.parse(JsonParser.java:438)
        at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:745)
        at com.google.api.client.json.JsonParser.parse(JsonParser.java:358)
        at com.google.api.client.json.JsonParser.parse(JsonParser.java:331)
        at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
        at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
        at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
        at com.dgt.ds.MainActivity$1.doInBackground(MainActivity.java:70)
        at com.dgt.ds.MainActivity$1.doInBackground(MainActivity.java:58)
        at android.os.AsyncTask$2.call(AsyncTask.java:287)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
        ... 5 more
        Caused by: java.lang.NumberFormatException: Invalid date/time format: 2013-08-05T10:27:27.449810
        at com.google.api.client.util.DateTime.parseRfc3339(DateTime.java:301)
        at com.google.api.client.util.Data.parsePrimitiveValue(Data.java:435)
        at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:795)
        ... 17 more

这是 Python 中的消息对象(我使用的是message_types.DateTimeField):

class DResponse(messages.Message):
    id = messages.StringField(1)
    created_at = message_types.DateTimeField(2)
    author = messages.StringField(3)
    description = messages.StringField(4, required=True)

我该如何解决这个问题?

【问题讨论】:

  • 这可能是 DateTimeField 的实现方式或 Java 客户端库中的错误。相同请求的 JSON 有效负载是什么样的?您可以访问应用程序的 API 资源管理器进行测试,地址为 https://yourappid.appspot.com/_ah/api/explorer
  • @bossylobster 它看起来像一个正确的 JSON 响应,DateTimeField 是 "created_at": "2013-08-05T10:27:27.449000"
  • 谢谢,我会做更多的挖掘工作。
  • 问题是 Python 戳记在小数点后有 6 位,而 Java 库预计正好是 3。这似乎是一个错误,但我不确定在哪里。

标签: android google-app-engine google-api-java-client google-cloud-endpoints google-api-client


【解决方案1】:

这是因为 protorpc.protojson.ProtoJson.encode_field 在原生 datetime.datetime 对象上是 using isoformat

这使用微秒而不是毫秒(因为 Python 中的 datetime 模块使用微秒),因此 Java 客户端库解析器失败。

对于短期修复,您可以做以下两件事之一:

  • 停止使用DateTimeField,只使用IntegerField,依靠您的客户端以整数形式发送时间戳
  • Monkey 补丁 protorpc/protojson.py 引用 ProtoJson 的子类,它的行为正确。本质上,不应使用isoformat(),而应使用小数点后只有 3 位的混合。

【讨论】:

  • 我到处搜索以找到解决此问题的方法,除了您的建议外找不到任何其他方法。使用 datetime.replace(microsecond=0) 也失败了。
  • protorpc/protojson.py 现在应该修复了吗?我认为不需要补丁。
  • 我认为当前的 SDK 仍然存在错误
  • SDK 不影响服务端错误。很抱歉,我不再在 Google 工作,所以除了我最初的回答之外,我无能为力。
  • SDK 的问题是服务器序列化数据的方式错误。
猜你喜欢
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 2014-05-27
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多