我想知道如何确定一个空的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。 但并非每个服务器都设置此字段。
有什么建议吗?
答案 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);
}
这里的假设是,为了代码的简单性和可操作性,你不需要区分空实体和没有实体,如果有响应,你还是需要阅读它。