2017-06-27 6 views
1

ジャージーを使用し、JSON処理用にMoxyの代わりにGSONを使用することにしました(Moxyにはセッターが必要です)。 サブクラスで非常に厄介な問題を除いて、今まではすべて正常に動作します。カスタムGsonProviderは、各呼び出しごとに明示的に登録されていない限り認識されません。ただし、アプリケーションをTomcatにデプロイすると認識されています。GSONを使用しているときにJerseyTestでMessageBodyProviderNotFoundExceptionがスローされる

マイResourceConfigGsonProvider

@ApplicationPath("") 
public class MyResourceConfig extends ResourceConfig { 

    public MyResourceConfig() { 
     register(GsonProvider.class); 

     register(SomeResource.class); 
    } 
} 

実装(私はそれが私が体験し、問題に関連しているとは思わないが):MessageBodyProviderNotFoundException

@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class GsonProvider<T> implements MessageBodyReader<T>, MessageBodyWriter<T> { 

    private final Gson mGson; 

    public GsonProvider() { 
     mGson = new GsonBuilder().create(); 
    } 

    @Override 
    public boolean isReadable(Class<?> type, Type genericType, 
           Annotation[] annotations, MediaType mediaType) { 
     return true; 
    } 

    @Override 
    public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, 
         MediaType mediaType, MultivaluedMap<String, String> httpHeaders, 
         InputStream entityStream) throws IOException, WebApplicationException { 

     InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); 
     try { 
      return mGson.fromJson(reader, type); 
     } finally { 
      reader.close(); 
     } 
    } 

    @Override 
    public boolean isWriteable(Class<?> type, Type genericType, 
           Annotation[] annotations, MediaType mediaType) { 
     return true; 
    } 

    @Override 
    public long getSize(T t, Class<?> type, Type genericType, 
         Annotation[] annotations, MediaType mediaType) { 
     return -1; 
    } 

    @Override 
    public void writeTo(T t, Class<?> type, Type genericType, Annotation[] annotations, 
         MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, 
         OutputStream entityStream) throws IOException, WebApplicationException { 

     PrintWriter printWriter = new PrintWriter(entityStream); 
     try { 
      String json = mGson.toJson(t); 
      printWriter.write(json); 
      printWriter.flush(); 
     } finally { 
      printWriter.close(); 
     } 
    } 
} 

このテスト結果:

public class SomeResourceTest extends JerseyTest { 
    @Override 
    public Application configure() { 
     return new MyResourceConfig(); 
    } 

    @Test 
    public void someApi_200Returned() throws Exception { 
     // Arrange 
     // Act 
     SomeResponse response = 
       target("/somepath") 
         .request() 
         .post(Entity.json(""), SomeResponse.class); 
     // Assert 
     assertThat(response.getStatus(), is(200)); 
    } 
} 

私はこの問題を解決するために要求のためにister GsonProvider。以下の変更は、テストパスます:だから

public class SomeResourceTest extends JerseyTest { 
    @Override 
    public Application configure() { 
     return new MyResourceConfig(); 
    } 

    @Test 
    public void someApi_200Returned() throws Exception { 
     // Arrange 
     // Act 
     SomeResponse response = 
       target("/somepath") 
         .register(GsonProvider.class) 
         .request() 
         .post(Entity.json(""), SomeResponse.class); 
     // Assert 
     assertThat(response.getStatus(), is(200)); 
    } 
} 

を、MyResourceConfigGsonProviderの登録は、展開のために良いですが、JerseyTestはリクエストごとの追加登録が必要です。

私はそれで暮らすことができますが、それは迷惑で時間がかかり、他のチームメンバーと通信するのが難しくなります。この問題の解決策はありますか?

答えて

1

あなたはスタックトレースを表示していませんが、注意深く見ると実際にはクライアントサイドのエラーであることがわかります。何をする必要があなたはconfigureClient方法POJO

@Override 
public void configureClient(ClientConfig config) { 
    config.register(GsonProvider.class) 
} 

に応じJSONをデシリアライズしようとしているので、また、クライアントとのgsonプロバイダを登録しているあなたは無効にすることができJerseyTest方法です。

+0

はい!クライアントがスタンドアロンエンティティであることに気づきませんでした。ありがとうございました – Vasiliy

+0

私は任意の呼び出しでプロバイダーを登録しなければならなかったし、それは動作しました。しかし、私はこれを解決する一般的な方法があると確信していました。あなたの答えはまさに私が必要としていたものです。このロジックを 'MyJerseyTest'の基底クラスに入れて、人生は再び良いです:) – Vasiliy

関連する問題