我使用Jersey并决定使用GSON而不是Moxy进行JSON处理(不喜欢Moxy需要setter的事实)。MessageBodyProviderNotFoundException在使用GSON时在JerseyTest中抛出
一切工作正常,直到现在,除了在我的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));
}
}
为了解决这个问题我reg请求的是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