MessageBodyProviderNotFoundException выбрасывается в JerseyTest при использовании GSON
Я использую Джерси и решил использовать GSON вместо Moxy для обработки JSON (мне не нравился тот факт, что Moxy требуются сеттеры).
До сих пор все работает нормально, кроме одного очень раздражающего вопроса в моем JerseyTest
подклассы: обычай GsonProvider
не распознается, если явно не зарегистрировано для каждого вызова. Тем не менее, он распознается, если я разверну приложение в Tomcat.
мой ResourceConfig
:
@ApplicationPath("")
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
register(GsonProvider.class);
register(SomeResource.class);
}
}
Реализация GsonProvider
(хотя я не думаю, что это связано с проблемой, с которой я сталкиваюсь):
@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();
}
}
}
Результаты этого теста в MessageBodyProviderNotFoundException
:
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));
}
}
Для решения этой проблемы я регистрируюсь 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));
}
}
Итак, регистрация GsonProvider
в MyResourceConfig
хорошо для развертывания, но JerseyTest
требует дополнительной регистрации за запрос.
Хотя я могу жить с этим, это раздражает, отнимает много времени и будет трудно общаться с другими членами команды. Любое решение для этой проблемы?
1 ответ
Вы не показали трассировку стека, но я уверен, что если вы внимательно посмотрите на нее, это покажет, что это на самом деле ошибка на стороне клиента. Вам нужно также зарегистрировать провайдера gson на клиенте, поскольку вы пытаетесь десериализовать ответ JSON для POJO.
@Override
public void configureClient(ClientConfig config) {
config.register(GsonProvider.class)
}
configureClient
метод является методом в JerseyTest
что вы можете переопределить.