从post请求中读取JAX-RS客户端中的响应主体

时间:2013-08-06 17:24:41

标签: java json web-services cxf jax-rs

在移动应用和网络服务之间有某种代理,我们对发布帖子请求时的响应感到困惑。我们收到状态为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)吗?

6 个答案:

答案 0 :(得分:124)

试试这个:

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

修改

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

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

答案 1 :(得分:13)

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

String output = response.readEntity(String.class)

这会按预期提供内容。

答案 2 :(得分:8)

对于我的用例,之前的答案都没有起作用,因为我正在编写一个服务器端单元测试,由于Unable to Mock Glassfish Jersey Client Response Object问题中描述的以下错误消息而失败:

sub only_number
{
        ($num) = @_;

        do{
                print "Type a Number: ";
                $num = <STDIN>;
                if($num =~ /\D+.*\n$/){
                        print "Thats is not a number. >:[ \n";
                }
        } until($num = $num + 0);
};
&only_number($num1);

do{
        print "What do you want to do? ";
        $operator = <STDIN>;
        if($operator !~ /\/|\*|\-|\+/){
                print "Thats not a valid character (-_-;).\n"
        }
} until ($operator =~ /\/|\*|\-|\+/);

&only_number($num2);

if($operator eq "*\n"){
        $result = $num1*$num2;
}
elsif($operator eq "/\n"){
        $result = $num1/$num2;
}
elsif($operator eq "+\n"){
        $result = $num1+$num2;
}
elsif($operator eq "-\n"){
        $result = $num1-$num2;
}
print "your answer is $result\n";

exit;

此异常发生在以下代码行中:

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

答案 3 :(得分:3)

我也有同样的问题,试图运行一个单元测试调用使用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

希望这有帮助!

答案 4 :(得分: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

答案 5 :(得分:0)

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

我使用以下Maven依赖项:

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

致谢

Carlos Cepeda