HttpClient:确定响应中的空实体

时间:2013-06-09 15:13:29

标签: java android httpclient

我想知道如何确定一个空的http响应。 使用空的http响应我的意思是,http响应只会设置一些标题,但包含一个空的http主体。

例如:我对网络服务器进行HTTP POST,但网络服务器只返回我的HTTP POST的状态代码,而不是其他内容。

问题是,我在apache HttpClient上编写了一个小的http框架来进行自动json解析等。所以这个框架的默认用例是发出请求并解析响应。但是,如果响应不包含数据,如上例中所述,我将确保我的框架跳过json解析。

所以我这样做:

HttpResponse response = httpClient.execute(uriRequest);
HttpEntity entity = response.getEntity();
if (entity != null){
    InputStream in = entity.getContent();
    // json parsing
}

但实体总是!= null。并且检索到的输入流是!= null。有没有一种简单的方法来确定http正文是否为空?

我看到的唯一方法是服务器响应包含Content-Length头字段设置为0。 但并非每个服务器都设置此字段。

有什么建议吗?

2 个答案:

答案 0 :(得分:6)

HttpClient中,getEntity() 可以返回null。请参阅the latest samples

但是, empty 实体和 no 实体之间存在差异。听起来你有一个实体。 (抱歉是迂腐 - 只是HTTP很迂腐。:)关于检测空实体,你试过从实体输入流中读取吗?如果响应是空实体,则应立即获得EOF。

您是否需要确定实体是否为空而不从实体主体读取任何字节?根据上面的代码,我不认为你这样做。如果是这种情况,您可以使用PushbackInputStream将实体InputStream打包并检查:

HttpResponse response = httpClient.execute(uriRequest);
HttpEntity entity = response.getEntity();
if(entity != null) {
    InputStream in = new PushbackInputStream(entity.getContent());
    try {
        int firstByte=in.read();
        if(firstByte != -1) {
            in.unread(firstByte);
            // json parsing
        }
        else {
            // empty
        }
    }
    finally {
        // Don't close so we can reuse the connection
        EntityUtils.consumeQuietly(entity);
        // Or, if you're sure you won't re-use the connection
        in.close();
    }
}

最好不要将整个响应读入内存,以防它变大。此解决方案将使用常量内存(4个字节:)测试空白。

编辑<pedantry>在HTTP中,如果请求没有Content-Length标头,则应该有Transfer-Encoding: chunked标头。如果没有Transfer-Encoding: chunked标头,那么您应该具有 no 实体而不是实体。 </pedantry>

答案 1 :(得分:1)

我建议使用类EntityUtils来获取String的响应。如果它返回空字符串,则响应为空。

String resp = EntityUtils.toString(client.execute(uriRequest).getEntity())
if (resp == null || "".equals(resp)) {
    // no entity or empty entity
} else {
    // got something
    JSON.parse(resp);
}

这里的假设是,为了代码的简单性和可操作性,你不需要区分空实体和没有实体,如果有响应,你还是需要阅读它。