在移动应用程序和网络服务之间有某种代理,我们对发出发布请求时的响应感到困惑。我们收到状态为 200 的响应:好的。但是我们无法找到/提取 JSON 响应正文。
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(WEBSERVICE_BASE_LOCATION + "mobileDevices?operatorCode=KPNSCP");
String jsonString = "{\"osVersion\":\"4.1\",\"apiLevel\":16,\"devicePlatform\":\"ANDROID\"}";
Builder builder = webTarget.request();
Response response = builder.post(Entity.json(jsonString));
我们正在使用 JAX-RS。 有人可以提供一些提示以从服务器响应中提取 JSON 正文 (
String
) 吗?
试试这个:
String output = response.getEntity(String.class);
编辑
感谢 @Martin Spamer 提到它仅适用于 Jersey 1.x jar。对于 Jersey 2.x 使用
String output = response.readEntity(String.class);
我刚刚找到了 jaxrs-ri-2.16 的解决方案 - 只需使用
String output = response.readEntity(String.class)
这提供了预期的内容。
对于我的用例,之前的答案均无效,因为我正在编写一个服务器端单元测试,该测试由于以下错误消息而失败,如无法模拟 Glassfish Jersey 客户端响应对象 问题中所述:
java.lang.IllegalStateException: Method not supported on an outbound message.
at org.glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.java:145)
at ...
此异常发生在以下代码行:
String actJsonBody = actResponse.readEntity(String.class);
修复是将问题代码行变成:
String actJsonBody = (String) actResponse.getEntity();
我也有同样的问题,试图运行一个使用
readEntity
的单元测试调用代码。不能在生产代码中使用 getEntity
,因为它只返回 ByteInputStream
而不是正文的内容,而且我无法添加仅在单元测试中命中的生产代码。
我的解决方案是创建一个响应,然后使用 Mockito 间谍来模拟
readEntity
方法:
Response error = Response.serverError().build();
Response mockResponse = spy(error);
doReturn("{jsonbody}").when(mockResponse).readEntity(String.class);
请注意,您不能使用
when(mockResponse.readEntity(String.class)
选项,因为它会抛出相同的 IllegalStateException
.
希望这有帮助!
根据文档,Jax rs 2.0 中的 getEntity 方法返回一个 InputStream。 如果需要将InputStream转成JSON格式的String,需要对这两种格式进行强制转换。 例如在我的例子中,我实现了下一个方法:
private String processResponse(Response response) {
if (response.getEntity() != null) {
try {
InputStream salida = (InputStream) response.getEntity();
StringWriter writer = new StringWriter();
IOUtils.copy(salida, writer, "UTF-8");
return writer.toString();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
return null;
}
我为什么要实现这个方法。 因为在 differets 博客中读到,许多开发人员在使用下一个方法的 jaxrs 版本中遇到了同样的问题
String output = response.readEntity(String.class)
和
String output = response.getEntity(String.class)
第一个作品使用 com.sun.jersey 库中的 jersey-client,第二个作品使用 org.glassfish.jersey.core 中的 jersey-client 找到。
这是呈现给我的错误: org.glassfish.jersey.client.internal.HttpUrlConnector$2 无法转换为 java.lang.String
我使用以下 Maven 依赖项:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>
我不知道为什么readEntity方法不起作用。希望你能使用解决方案。
卡洛斯塞佩达
实现代码的修改我找到了阅读方法对我不起作用的原因。问题是我的项目使用 jersey 1.x 的依赖项之一。 更新版本,调整客户端,就可以了。
我使用以下 Maven 依赖项:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>
问候
卡洛斯塞佩达
使用 Kotlin 的相同版本的答案
(response.entity as InputStream).bufferedReader().use { it.readText() }