ジャージーを使用し、JSON処理用にMoxyの代わりにGSONを使用することにしました(Moxyにはセッターが必要です)。 サブクラスで非常に厄介な問題を除いて、今まではすべて正常に動作します。カスタムGsonProvider
は、各呼び出しごとに明示的に登録されていない限り認識されません。ただし、アプリケーションをTomcatにデプロイすると認識されています。GSONを使用しているときにJerseyTestでMessageBodyProviderNotFoundExceptionがスローされる
マイResourceConfig
:GsonProvider
の
@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));
}
}
を、MyResourceConfig
でGsonProvider
の登録は、展開のために良いですが、JerseyTest
はリクエストごとの追加登録が必要です。
私はそれで暮らすことができますが、それは迷惑で時間がかかり、他のチームメンバーと通信するのが難しくなります。この問題の解決策はありますか?
はい!クライアントがスタンドアロンエンティティであることに気づきませんでした。ありがとうございました – Vasiliy
私は任意の呼び出しでプロバイダーを登録しなければならなかったし、それは動作しました。しかし、私はこれを解決する一般的な方法があると確信していました。あなたの答えはまさに私が必要としていたものです。このロジックを 'MyJerseyTest'の基底クラスに入れて、人生は再び良いです:) – Vasiliy