1

私は現在、REST(JAXRS)の実装にResteasy-mobileを使用し、JSONとの間のシリアル化にJacksonを使用するAndroidアプリに取り組んでいます。後者は、バックグラウンドでResteasyによって実行されます。

サーバーサイド私はJerseyWebサービスを持っており、JSONとの間のシリアル化にもjacksonを使用しています。

Resteasyクライアントとwebresourceの両方が、次のようなJAXRS注釈付きインターフェースを実装します。

    @Path("/equipment")
    @Consumes({"application/json"})
    @Produces({"application/json"})
    public interface AndroidEquipmentResourceIF
    {
      @GET 
      public Model getModel();

      @GET 
      @Path("/version") 
      public String getVersion();

      @GET 
      @Path("/{eId}") 
      public List<Equipment> getEquipmentListWithId(@PathParam("eId") String eId);
    }

クライアント側では、このインターフェイスはファクトリにロードされ、このインターフェイスを使用してオブジェクトを返します。このインターフェイスは、メソッドが呼び出されたときにHTTP /URL/シリアル化プロセスを処理します。

無効なIDを持つEquipmentエンティティが呼び出されると、WebApplicationExceptionエンティティが見つからなかった場合、サーバーはaをスローします。クライアントサイドでは、これによりメソッドがnullを返す可能性があります。

404 - Not foundまたはのようなステータスコードで何かをしたい場合は401 - Unauthorized、おそらく応答オブジェクトが必要ですか?ResteasyとJerseyはバックグラウンドでResponseオブジェクトを処理すると思いますが、Resteasyを使用してResponseオブジェクトまたはステータスコードにアクセスする方法はありますか?

編集1:2番目のオプションについて言及するのを忘れました。オブジェクトを応答オブジェクトでラップできることに気づきました。したがって、すべての特定のドメインオブジェクトの戻り型をResponseに置き換え、オブジェクトを何らかの方法で応答でラップすると、Responseオブジェクトからオブジェクトを抽出できますか?ステータスコードを見ることができるというだけで、これは私にはあまりきれいに聞こえません。また、JSONを手動で解析することはできるだけ避けたいと思います。

EDIT2:インターセプトが可能であることが判明したためWebApplicationException、ResteasyクライアントはClientResponseFailure例外をスローします。これは、インターセプターでキャッチされる可能性があります。問題は、例外がスローされないことです。どこかでインフェナイトループに引っかかっているようです。

次の例外が発生します。

10-26 10:52:10.048: E/AndroidRuntime(282): Caused by: java.lang.StackOverflowError
10-26 10:52:10.048: E/AndroidRuntime(282):  at java.util.regex.Matcher.reset(Matcher.java:151)
10-26 10:52:10.048: E/AndroidRuntime(282):  at java.util.regex.Matcher.reset(Matcher.java:211)
10-26 10:52:10.048: E/AndroidRuntime(282):  at java.util.regex.Matcher.<init>(Matcher.java:127)
10-26 10:52:10.048: E/AndroidRuntime(282):  at java.util.regex.Pattern.split(Pattern.java:405)
10-26 10:52:10.048: E/AndroidRuntime(282):  at java.util.regex.Pattern.split(Pattern.java:355)
10-26 10:52:10.048: E/AndroidRuntime(282):  at java.lang.String.split(String.java:2125)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.plugins.delegates.MediaTypeHeaderDelegate.parse(MediaTypeHeaderDelegate.java:33)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.plugins.delegates.MediaTypeHeaderDelegate.fromString(MediaTypeHeaderDelegate.java:18)
10-26 10:52:10.048: E/AndroidRuntime(282):  at javax.ws.rs.core.MediaType.valueOf(MediaType.java:173)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getMediaType(BaseClientResponse.java:362)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:346)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:319)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:442)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.copyFromError(BaseClientResponse.java:94)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.ClientResponseFailure.<init>(ClientResponseFailure.java:32)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:488)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:479)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.readFrom(BaseClientResponse.java:384)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:346)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:319)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:442)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.copyFromError(BaseClientResponse.java:94)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.ClientResponseFailure.<init>(ClientResponseFailure.java:32)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:488)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:479)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.readFrom(BaseClientResponse.java:384)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:346)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:319)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:442)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.core.BaseClientResponse.copyFromError(BaseClientResponse.java:94)
10-26 10:52:10.048: E/AndroidRuntime(282):  at org.jboss.resteasy.client.ClientResponseFailure.<init>(ClientResponseFailure.java:32)
4

1 に答える 1

2

次のように機能しました。

Resteasy-mobileは、JBOSS Resteasy2.2.1GAのプルーニングバージョンです。Androidで動作するように、多くのものが削除されました。しかし、少し多すぎます。

aClientResponseFailureがスローされると、そのエンティティがByte配列にキャストされ、にコピーするために再度読み取られることがわかりましたClientResponseFailure。問題は、プルーニングされたバージョンには、文字列とテキスト/プレーン用のメッセージボディリーダー/ライターのみが含まれ、バイト配列用は含まれないことです。したがって、エンティティを読み取ろうとすると、と互換性のあるClientResponseFailureを見つけることができないために新しいものをスローしようとします。次に、このエンティティをバイト配列に再度キャストし、再度読み取ろうとします。これにより、。で終わる無限ループに入ります。MessageBodyReaderByte[]StackOverflowError

剪定されていないバージョンのResteasyから欠落しているクラスをclasspath(atByteArrayProviderおよび)に追加することにより、 (リンク)は魅力のように機能します!ReadFromStreamorg.jboss.resteasy.plugins.providers.ByteArrayProviderorg.jboss.resteasy.util.ReadFromStreamClientErrorInterceptor

編集:私は少し早すぎて、まだ魅力のように機能していませんでした。ResteasyProviderFactoryも、Androidで動作するように変更されました。.getInstance()メソッドは新しいインスタンスを返し続けるため、ClientErrorInterceptorを次のように登録するResteasyProviderFactory.getInstance().addClientErrorInterceptor(new DataExceptionInterceptor());と機能しません。ProxyFactoryは、ResteasyProviderFactoryの新しいインスタンスを内部的に使用します。

この問題を回避するには、インターセプターの追加に使用されるResteasyProviderFactoryをに渡す必要がありProxyFactory.create()ます。

このような:

ResteasyProviderFactory pf;
BasicHttpParams params;

pf = ResteasyProviderFactory.getInstance();

pf.addClientErrorInterceptor(new DataExceptionInterceptor());

params = new BasicHttpParams();
HttpProtocolParams.setVersion(params,
                              HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,
                                     HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params,
                                        false);
return ProxyFactory.create(AndroidEquipmentResourceIF.class,
                           ProxyFactory.createUri(requestURI),
                           new ThreadSafeApacheHttpClient4Executor(params),
                           pf);
于 2012-10-29T10:04:28.763 に答える