gpt4 book ai didi

java - 使用 GSON 时在 JerseyTest 中抛出 MessageBodyProviderNotFoundException

转载 作者:行者123 更新时间:2023-11-30 06:38:38 25 4
gpt4 key购买 nike

我使用 Jersey 并决定使用 GSON 而不是 Moxy 进行 JSON 处理(不喜欢 Moxy 需要 setter )。

到目前为止,一切工作正常,除了我的 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));
}
}

因此,在 MyResourceConfig 中注册 GsonProvider 有利于部署,但 JerseyTest 需要针对每个请求进行额外注册。

虽然我可以忍受这一点,但这很烦人、耗时,而且很难与其他团队成员沟通。这个问题有什么解决办法吗?

最佳答案

您还没有显示堆栈跟踪,但我很确定如果您仔细观察它,它会表明它实际上是客户端错误。您需要做的就是向客户端注册 gson 提供程序,因为您正在尝试将响应 JSON 反序列化为 POJO

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

configureClient 方法是 JerseyTest 中的一个可以重写的方法。

关于java - 使用 GSON 时在 JerseyTest 中抛出 MessageBodyProviderNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44779111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com