RPCを使用してGAEとAndroidでアプリケーションを開発しています。しかし、Android からサーバーに RPCall を送信しようとすると、次のエラーが発生します。
03-14 12:00:57.445: E/AndroidRuntime(30718): FATAL EXCEPTION: IntentService[domiii.1992@gmail.com]
03-14 12:00:57.445: E/AndroidRuntime(30718): java.lang.RuntimeException: Could not parse payload: payload[0] = <
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.autobean.vm.impl.JsonSplittable.create(JsonSplittable.java:70)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.autobean.shared.impl.StringQuoter.split(StringQuoter.java:73)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.autobean.shared.AutoBeanCodex.decode(AutoBeanCodex.java:54)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$StandardPayloadDialect.processPayload(AbstractRequestContext.java:323)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$5.onTransportSuccess(AbstractRequestContext.java:1108)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.cloudsmsplus.util.AndroidRequestTransport.send(AndroidRequestTransport.java:68)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.doFire(AbstractRequestContext.java:1102)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.fire(AbstractRequestContext.java:569)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.requestfactory.shared.impl.AbstractRequest.fire(AbstractRequest.java:54)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.web.bindery.requestfactory.shared.impl.AbstractRequest.fire(AbstractRequest.java:59)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.cloudsmsplus.c2dm.DeviceRegistrar.registerOrUnregister(DeviceRegistrar.java:70)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.cloudsmsplus.C2DMReceiver.onRegistered(C2DMReceiver.java:51)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.android.c2dm.C2DMBaseReceiver.handleRegistration(C2DMBaseReceiver.java:191)
03-14 12:00:57.445: E/AndroidRuntime(30718): at com.google.android.c2dm.C2DMBaseReceiver.onHandleIntent(C2DMBaseReceiver.java:110)
03-14 12:00:57.445: E/AndroidRuntime(30718): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
03-14 12:00:57.445: E/AndroidRuntime(30718): at android.os.Handler.dispatchMessage(Handler.java:99)
03-14 12:00:57.445: E/AndroidRuntime(30718): at android.os.Looper.loop(Looper.java:137)
03-14 12:00:57.445: E/AndroidRuntime(30718): at android.os.HandlerThread.run(HandlerThread.java:60)
アプリにアクセスするには、ユーザーを認証する必要があるため、すべての URL に対してセキュリティ制約を * に設定します。Cookie を生成しているにもかかわらず、このエラーが発生します。私が受け取る応答はログインページだと思います。
私の場合、RPCall を送信してデバイスを C2DM に登録します。私が使用するコードのほとんどは、Appengine に接続された Android プロジェクトで生成されたものです。誰かがすでにその回避策または修正を見つけましたか。
PS: GAE 1.6.3、Android API v8、GWT 2.4.0 を使用しています (ただし、これは問題ではないと思います)。
編集:
わかりました、新しいものを見つけました。RPC を使用して Android から App Engine に何かを送信すると、クライアントは実際には認証されません。トークンを取得し、続いて Cookie を取得するだけで、(私が思うに) RequestFactory には追加のデータ フィールドとして Cookie が含まれます。したがって、App Engine 上の私の web.xml は次のようになります。
<!-- Require user login for every access -->
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
私のアプリケーションにアクセスするには、ユーザーが要求している URL に関係なく、ユーザーを認証する必要があります。RequestFactory はログイン ページの html でサーバーの応答を認証されないため、Android クライアントは「ペイロードを解析できませんでした」というエラーをスローします。奇妙なことに、GWT 側から認証済み RPC を送信できるのに、なぜこの API の開発者がそのようにしたのか理解できません。GWT 側はそれらの認証済み呼び出しを送信でき、Android 側はそうではありません。それらを送ることができます。
ここで行ったことは、web.xml に次の行を追加して、セキュリティ制約から gwtRequest サーブレットを除外したことです。
<security-constraint>
<web-resource-collection>
<url-pattern>/gwtRequest</url-pattern>
</web-resource-collection>
</security-constraint>
また、App Engine に接続された新しい Android プロジェクトを作成すると、web.xml が必要な認証を ProjectName.html に設定するだけであることに気付きました。