HttpClient:确定响应中的空实体

soc*_*qwe 3 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
}
Run Code Online (Sandbox Code Playgroud)

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

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

有什么建议?

sig*_*ned 6

HttpClient,getEntity() 可以返回null.查看最新样本.

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

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:<pedantry>在HTTP中,如果请求没有Content-Length标题,那么应该有一个Transfer-Encoding: chunked标题.如果没有Transfer-Encoding: chunked标题,那么你应该没有实体而不是实体.</pedantry>