从发布请求中读取JAX-RS客户端中的响应正文


75

在移动应用程序和Web服务之间具有某种代理,发出发布请求时的响应使我们感到困惑。我们收到状态为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。有人可以提供一些提示来String从服务器响应中提取JSON正文()吗?


4
我们必须将其更改为:String output = response.readEntity(String.class);要使其起作用。非常感谢!
user2657714

Answers:


169

尝试这个:

String output = response.getEntity(String.class);

编辑

感谢@Martin Spamer提及它仅适用于Jersey 1.x罐子。适用于Jersey 2.x

String output = response.readEntity(String.class);

46
这仅适用于泽西岛(Jersey):2.x及更高版本的OP正在使用的Jax 1.x(我们可以从他对ClientBuilder.newClient()的使用中看出来)。回应是response.readEntity(String.class);
Martin Spamer 2014年

3
这对于jaxrs-ri-2.16不起作用,在这里您将获得org.glassfish.jersey.client.HttpUrlConnector$2@1255b1d1输出。
col.panic

谢谢,我在使用getEntity()读取响应消息正文时陷入了很长一段时间。getEntity()仅适用于Jersey 1.x,Jersey 2.0支持response.readEntity()以获取响应消息正文。
spectre007,2016年

请注意,如果获得了com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String,则需要手动读取响应流以获取JSON字符串。那对我来说是泽西1.19。
dvlcube

17

我刚刚找到了jaxrs-ri-2.16的解决方案-只需使用

String output = response.readEntity(String.class)

这将按预期方式提供内容。


14
泽西岛的开发商让我发疯。每种版本方法的命名方式和/或整个工作流程都将发生巨大变化。这就像玩矿工游戏。从头开始查找所有地雷。
Alfishe

2
你不喜欢敏捷吗?:)
异想天开

8
@异想天开,我认为他喜欢向后兼容:)
赫里斯托·弗里加佐夫

13

对于我的用例,以前的答案都无效,因为我正在编写服务器端单元测试,但由于出现以下错误消息而失败,如无法模拟嘲笑客户端响应对象问题中所述:

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();

3
getEntity不会自动读取任何支持InputStream的内容,因此请小心。
2016年

4

我也遇到了同样的问题,试图运行使用的单元测试调用代码readEntity。无法getEntity在生产代码中使用,因为这只会返回aByteInputStream而不是主体的内容,并且我无法添加仅在单元测试中被击中的生产代码。

我的解决方案是创建一个响应,然后使用Mockito间谍模拟该readEntity方法:

Response error = Response.serverError().build();
Response mockResponse = spy(error);
doReturn("{jsonbody}").when(mockResponse).readEntity(String.class);

请注意,您不能使用该when(mockResponse.readEntity(String.class)选项,因为它会抛出相同的结果IllegalStateException

希望这可以帮助!


1
谢谢!您可能是第一个真正了解OP的问题的人。对于您在那里其他所有的第一反应者:没有人关心您有多聪明。他们想解决他们的问题。他们对为什么jersey不允许您在单元测试中调用readResponse感兴趣。
John Calcote

0

根据文档,Jax rs 2.0中的getEntity方法返回一个InputStream。如果需要将JSON格式的InputStream转换为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;
}

为什么我实现这种方法。因为在差异博客中读到很多开发人员都遇到相同的问题,所以使用以下方法在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方法不起作用。希望您可以使用该解决方案。

卡洛斯·塞佩达(Carlos Cepeda)


0

实现代码的修订版后,我找到了导致阅读方法对我不起作用的原因。问题是我的项目使用jersey 1.x的依赖项之一。更新版本,调整客户端即可使用。

我使用以下Maven依赖项:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

问候

卡洛斯·塞佩达(Carlos Cepeda)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.