Httpclient4.4之原理(请求执行)(3)

当实体收到一个进来的消息时,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. 消费实体内容

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9e6df74f30b5635d9e9708bc9e48a617.html