HttpCore学习----Blocking I/O部分---基本client的实现

HttpCore4.4点此到现在链接

基本概念:

  1. http message: 由一系列消息头,以及可选的消息体组成,http request message header(请求消息头)包括请求行(request line)以及一系列header fields,反之,响应消息头包括状态行(status line)和一系列header fields, 请求行中,由请求方法,请求的资源的uri以及http协议版本组成,状态行中.由http协议,状态字,以及一个说明信息组成
  2. http entity: http实体,说白了就是http的请求或响应中携带的你所请求的资源的具体内容,也就是消息体(实体的内容很多,有字节实体,文本实体,文件实体,字符串实体等等,)
  3. http protocol processor: 这个部分主要负责处理http协议当中一些特殊的部分,由一系列拦截器组成,也可以成为拦截器的容器,它用于加工一个http请求或者响应,?什么意思?举个例子说,我们在发送http请求的时候,通常在消息头里面会携带一个请求时间的消息头,那么这个请求时间要是让我们自己来写该多多麻烦.于是就提供了RequestDate(),ResponseDate()拦截器,当我们包装好一个http请求/响应之后,再通过它,让拦截器加工一下,就可以自动的帮我们生成一些http请求/响应的信息了.
  4. http executiopn context : http执行上下文,在一个程序执行的过程当中(某个进程),上下文是指维护程序运行所需的全部状态信息,这是一个抽象的概念,它表明的是,我做一件事情,所需要的全部东西,都应该满足某种状态,那么在这里就是维护http 交互所需要的信息,打个比方,我们要在淘宝上面买东西,我们都知道http是一种无状态协议(无状态是指通信双方不会保证通信的可靠,不会记录事务),那么我们选中一件商品之后,然后再打开购物车的页面,按照http协议,淘宝怎么知道我是不是刚刚选中了这件商品的人?那么久的采取一定的措施维护啊(session , cookie),维护这种状态的东西,就是http execution context..(其实很大程度上,需要自己去定义和修改这个http execution context 的具体实现)

开始阻塞I/O的学习
Blocking HTTP connection: 这是对http连接的一种抽象,在这个连接之上,我们传递Request和获取Response, 通常情况下,我们不需要对这条连接直接操作,而是通过更高层的协议处理组件来间接的在这条连接之上进行传输请求的操作,(通常越高层,意味着需要做的技术方面的考量就越少,因为很多不必要的成分,都被高层与低层之间的协议(或者接口)封装了),但是在必要的时候,依然可以对这个Connection进行操作,例如要获得远程连接的route,或者socket是否超时等.
//下面给出一个使用连接,来发送http请求,并且获取响应的例子

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.impl.DefaultBHttpClientConnection;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.util.EntityUtils;

public class BlockingHttpClient {
    public static void main(String arg0[]) throws UnknownHostException, IOException, Exception{


        /**
         * 先创建前面基本概念中需要的组件
         */
        // 创建一个http processor,并且为其添加拦截器
        HttpProcessor httpProcessor=HttpProcessorBuilder.create()
                .add(new RequestContent())//处理request请求的,content-length的信息,也就消息长度
                .add(new RequestTargetHost())//处理host 信息
                .build();
        //创建一个http上下文
        HttpCoreContext coreContext=new HttpCoreContext();
        //创建一个HttpHost对象,并且将其添加到上下文对象中,host对象,代表connection指向的route
        HttpHost host=new HttpHost("www.baidu.com",80);//
        coreContext.setTargetHost(host);

        /**
         * 下面开始创建一条Block I/O http connection,并且为其绑定Socket,之后,新建一个request,通过HttpProcessor处理之后发送给host,并且返回response
         */
        DefaultBHttpClientConnection connection=new DefaultBHttpClientConnection(8*1024);//参数代表的是,这个连接的缓存大小(buffer)
        connection.bind(new Socket(host.getHostName(),host.getPort()));
        HttpRequest request=new BasicHttpRequest("GET", "/");
        //之前说过,我们一般不对Connection直接进行操作,那么怎么操作呢?我们用一个更高层次的协议组件,这个组件已经为我们封装好了细节的实现
        //它的名字叫HttpRequestExecutor
        HttpRequestExecutor requestExecutor=new HttpRequestExecutor();
        requestExecutor.preProcess(request, httpProcessor, coreContext);//该方法的含义是初始化这个request,还记得前面说过,需要对httpRequest进行加工吗?
        //获取response
        HttpResponse response=requestExecutor.execute(request, connection, coreContext);//执行去了
        System.out.println("--->  reponse status line "+response.getStatusLine());
        //获取response中的entity
        org.apache.http.HttpEntity entity=response.getEntity();
        System.out.println(EntityUtils.toString(entity,"utf-8"));
        connection.close();

        //那么?我是不是可以不用HttpRequestExecutor来获取呢?当然也可以
        //给3秒钟的时间,让上面的去释放连接
        Thread.sleep(3000);

        System.out.println("------> 开始第二个操作  ");
        //下面开始不用HttpRequestExecutor
        connection.bind(new Socket(host.getHostName(),host.getPort()));
        httpProcessor.process(request, coreContext);//处理一下这个request
        connection.sendRequestHeader(request);//发送请求
        connection.flush();//刷新操作,刷新缓冲区是为了输出内容
        response = connection.receiveResponseHeader();//获得响应头
        connection.receiveResponseEntity(response);//获取entity
        entity = response.getEntity();
        System.out.println(EntityUtils.toString(entity));
        connection.close();
        System.out.println("------> 第二个结束 ");
    }
}

根据以上,有一个需要注意的地方,那就是高层协议组件的使用,相比对下层直接操作而言,会简单很多,但同时需要约束也就相应增加,约束了增加往往是为了让我们更加专注的工作于我们需要的部分.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值