当实体收到一个进来的消息时,HttpEntity的getContentType方法和getContentLength方法能被用来读取请求header里的元数据:Content-Type和Content-Length(如果它们可用)。由于header的Content-Type能包含像text/plain或text/html这样的MIME类型的字符集(编码),HttpEntity的getContentEncoding()方法用来读取这个信息。 如果header不可用,长度将返回-1和内容类型为NULL。如果header的Content-Type是可用的,这个Header对象将返回。
创建一个输出消息的实体时,该数据是由实体的创建者提供,示例:
package httpclienttest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
public class T6 {
public static void main(String[] args) throws Exception{
StringEntity myEntity = new StringEntity("important message",
ContentType.create("text/plain","UTF-8"));
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);
}
}
输出为:
Content-Type: text/plain; charset=UTF-8
17
important message
17
5. 确保底层资源的释放
为了确保系统资源的释放,必须关闭与实体相关的内容流或者response自身:
package httpclienttest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Stream;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public class T7 {
public static void main(String[] args) {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://ifeng.com");
//使用java7中的语法,自动调用close()方法,所以这里没有显示调用
try(CloseableHttpResponse response = httpclient.execute(httpget)){
HttpEntity entity = response.getEntity();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(
entity.getContent(),StandardCharsets.UTF_8))){
Stream<String> sm = reader.lines();
sm.forEach(System.out::println);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
关闭内容流与关闭response之间的区别是,前者试图保持消费实体内容的基本连接是活的,而后者关闭连接并丢弃!请注意:一旦实体被完全写出,HttpEntity的writeTo(OutputStream)方法也要确保系统资源释放。如果调用HttpEntity的getContent()方法获得一个java.io.InputStream流的实例,在最后也是要关闭并释放资源的。
当使用流实体工作时,EntityUtils的consume(HttpEntity)方法能确保实体内容完全被消费掉,并自动后台关闭流来释放资源。
有种极少见的情况,请求响应的实体内容只有一小部分需要被检索,剩下的都不需要,而消费剩下的内容又有性能损耗,造成重用连接很高。这种情况下,可以直接关闭response来终止内容流!如下例:
package httpclienttest;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public class T8 {
public static void main(String[] args) {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://ifeng.com");
try (CloseableHttpResponse response = httpclient.execute(httpget)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int byteOne = instream.read();
int byteTwo = instream.read();
System.out.printf("%d,%d",byteOne,byteTwo);
// instream中剩下的内容不需要了!直接关闭response
}
}catch(Exception e){
e.printStackTrace();
}
}
}
这样连接不会被重用,而且所有级别的资源都会被释放!
6. 消费实体内容