欢迎

非常欢迎阅读本文,本文主要介绍HttpCore是如何工作的。

你应该知道HTTP是一种用于在客户端与服务端进行消息交换的协议。它使用的特别广泛,它通常运行在TCP/IP或者安全的TLS/SSL之上。

Apache有一个HTTP协议的客户端实现Commons HttpClient。通俗地讲,称它为基于3.X的或者老代码。很多人都从中受益,但老代码在设计上有一些严重的限制。例如,有一个叫做HttpMethodBase的类,它同时表示一个请求和一个响应,它同时实现了两者的逻辑。这种将不同的功能放在一起的设计,让它很难维护,也很难进行扩展。

因此,我们启动了它的后继项目,HttpComponents。基于老代码中经验和教训,使用新的方法来实现HTTP协议。最终,使用不现的模块来处理不同的方面。从HttpCore的名字可以看出来,这个模块处于核心的地位。它被定义为其他模块的基础。

HttpCore处理HTTP消息的表示、传输逻辑包括发送和接收消息。它还被定义为一种基础框架,方便其他模块进行扩展其功能。与老代码不同,它不仅仅是HTTP客户端的实现,同时也可以做为服务端。正是因为它与老代码有这么大的不同,我们才决定将其放在新的包层次结构中,以免引起你的困惑。

Q:我有一个问题。
A:哦?什么问题,请讲。
Q:如果把它放在新的包层次结构中,那使用老代码的应用程序就不是使用新的了啊?
A:是的,由于老代码的设计上的限制,我们需要改动API。应用程序必须被重写,才能使用新的代码。没有办法避开这个问题。所有的新的包和老代码可以同时使用在相同的环境中,如Servlet引擎。

下面跟随我一起来了解org.apache.http。

消息

首先,我们需要处理消息的表示方式。如果你不知如何表示一个消息,你就不能发送或者接收它,对吧?因此,我们有一些用于创建HTTP消息的接口。RequestLine用于请求,StatusLine用于响应,它们都包含ProtocolVersion。ProtocolVersion是非常基础的,所以将其定义为类,而不是接口,当然,我们有HttpVersion继承自它。Header包含名字和值,值可以包含多个HeaderElement。最后还有一个表示消息体的HttpEntity。

Q:HttpVersion继承自ProtocolVersion?HttpCore中的协议不都是HTTP吗?

A:当前不是了。至少有一个不一样的协议,SIP(会话发起协议),它与HTTP有着相似的消息格式,只有协议的名字和版本是不同的。正是因为它们如此相似,我们试图保留它。

Q:明白了。

除了上述创建消息的接口,还要收集消息。每一个HttpMessage都有头,可以按照需求进行添加或者删除。HttpRequest添加请求行,HttpEntityEnclosingRequest是一个实体(后面都称为Entity)。HttpResponse添加状态行和一个Entity。为了方便集成到框架的工厂模式之中,有一些用于创建请求和响应的工厂接口。

Q:没有不带Entity的响应吗?

A:是的。你不需要给一个响应提供一个Entity,将它设置为null就好。对于请求,我们事先就知道是否需要一个Entity。对于GET请求,是不需要Entity的,这就是为什么提供了两个不同接口的原因。响应多数情况下是有Entity的,只有的极特别的情况下才是空。但是事先来处理一个响应是否有Entity使得API处理起来很麻烦,所以我们使用了相同的接口,都包含Entity。

Q:你说可以向HttpMessage添加或者从它删除头部,如果我想要一个只读的消息怎么办呢?

A:我们放弃了对消息是否可以修改进行区分的做法。因为那样将添加大量的接口,而且传播对类型的检查和向下转型。HttpCore面向的是知道她们在做什么的人群。如果你需要消息保持不变,简单的做法就是你不要去修改它。如果你执意在阻止修改的话,你可以自己实现这个一个接口,当修改的方法被调用时抛出异常。

接下来看看这个包里还有些什么东西,你会发现最重要的东西,这就是org.apache.http.message包。注意,所有的消息表示接口都有一些基础的实现类,但当你使用HttpCore写应用程序的时候不需要接触这些实现类。

Q:我不能看到GetRequest和PostRequest等的实现吗?

A:是的,在核心中并不包含这些类。核心就是当之无愧的核心。如果你需要一个GET请求,你只需要创建一个基本的请求,然后将GET作为HTTP方法的名字,对于POST和PUT也同样如此,除非你想用它们创建一个基础的实现封装请求。在客户端你可以找到一些默认的HTTP方法便利的类,对于核心来说,它们是多余的。

Q:为什么可以使用GET方法创建实体封装请求,GET请求不没有Entity吗,这一点我不太明白?

A:哈哈,你可以用核心类来做一些愚蠢的事情。核心就是核心,这意味着使用它的人应该清楚的知道他们在做什么。也许你想创建一个带实体的GET方法,用于测试服务器是如何应对非法请求的?

Q:这倒是挺有意思的,我从来没有想过这样做。

对于基础的实现还有其他的问题吗?好的,我们继续下一个问题。我们来看一看org.apache.http.entity。你可以在这里面看到一系列的消息实体。除了它们不再绑定为客户端,消息实体与老代码中实现基本没有什么差别。在老代码中,可以从字符串、字节数组、文件、输入流获取实体的内容。在连接中收到的消息,对应于BasicHttpEntity。在下面会看到连接的内容。我们还做一些工作,用于封装、缓存实体。使用EntityTemplate可以简化对一个实体的实现。

Q:在老代码中实体有多个组成部分吗?

A:根本上来讲,是这样的。但它们并不在核心当中。即使对于老代码来讲,它也被认为已经越出范围。它是在httpmime中的模块,而我们直接使用的是mime4j,它同样添加了额外的依赖。HttpCore根本没有外部的依赖。

对于实体还有问题吗?没有我们就开始介绍连接。

连接

从客户端发消息给服务端,或者从服务端返回消息给客户端都需要连接。在接口层,提供了HttpConnection,允许检查连接是否打开,关闭连接,断开连接,获取统计数据。实际用于发送或者接收数据使用的是HttpClientConnection或者HttpServerConnection,具体使用哪一个取决于你要做什么。显然,客户端连接允许你发送请求并接收响应,服务端连接允许你接收请求并发送响应。消息的发送或者获取就是通过我们上面介绍的连接进行的。发送消息头部和消息的实体需要两次调用。这样可以显式处理expect-continue的握手。

Q:我没有看到打开连接的方法啊?

A:你有鹰一样的眼睛,不是吗?你是对的,在接口中,没有打开一个连接的方法。在我们决定这一点上,花了大量的时间来讨论这个问题,打开一个连接比想象的更加复杂,所以我们没有将它们放在核心当中。

Q:如果我不能打开一个连接,那我该怎么使用连接呢?

A:API与实现不是一回事。在API中并没有类似open的方法,但你的实现中可以提供这样的方法。我们提供的默认实现,提供一个打开的套接口,你可以在任何时候创建它。

Q:套接口?我在接口当中也没有看到啊。是否可以设置TCP/IP的一些设置呢?

A:当前,了解套接口是十分有用的。但是,套接口并不属于核心API。有人可能会使用API而不是Java套接口与本地的库进行通信。我们会在下面介绍正确的实现方式。

Q:这是否意味着需要将实现类向下转型以获取IP和端口呢?

A:不,没有那么糟。有一个HttpInetConnection接口,提供了对本地及远程的IP和端口的访问,这只是一个可选的接口,但它是被默认实现支持的。你只需要向下转型为接口,而不是实现类。

在你问更多的问题之前,我们需要介绍点其他的东西,org.apache.http.impl,所有的连接的实现类都在这。不要迷惑,这样做只是为了代码的可维护性,你需要了解的只有两个类,DefaultHttpClientConnection和DefaultHttpServerConnection。提供了bind方法,传递一个打开的套接口,就打开了一个连接。由于继承自基类,也有getSocket方法。



https://wiki.apache.org/HttpComponents/GuidedTourOfHttpCore

畅游HttpCore的更多相关文章

  1. 山寨Unity3D?搜狐畅游的免费开源游戏引擎Genesis-3D

    在CSDN上看到了<搜狐畅游发布3D游戏引擎Genesis-3D 基于MIT协议开源>(http://www.csdn.net/article/2013-11-21/2817585-cha ...

  2. 搜狐畅游:每月给员工直系长辈2000元爱孝薪_企业新闻_265G产业频道

    搜狐畅游:每月给员工直系长辈2000元爱孝薪_企业新闻_265G产业频道 搜狐畅游:每月给员工直系长辈2000元爱孝薪

  3. 【BZOJ5020】【THUWC2017】在美妙的数学王国中畅游(Link-Cut Tree,组合数学)

    [BZOJ5020][THUWC2017]在美妙的数学王国中畅游(Link-Cut Tree,组合数学) 题解 Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙 ...

  4. 剑指Offer——搜狐畅游笔试题+知识点总结

    剑指Offer--搜狐畅游笔试题+知识点总结 情景回顾 时间:2016.9.24 10:00-12:00 地点:山东省网络环境智能计算技术重点实验室 事件:搜狐畅游笔试   注意事项:要有大局观,该舍 ...

  5. [THUWC2017]在美妙的数学王国中畅游

    [THUWC2017]在美妙的数学王国中畅游 e和sin信息不能直接合并 泰勒展开,大于21次太小,认为是0,保留前21次多项式即可 然后就把e,sin ,kx+b都变成多项式了,pushup合并 上 ...

  6. 在平衡树的海洋中畅游(一)——Treap

    记得有一天翔哥毒奶我们: 当你们已经在平衡树的海洋中畅游时,我还在线段树的泥沼中挣扎. 我觉得其实像我这种对平衡树一无所知的蒟蒻也要开一开数据结构了. 然后花了一天啃了下最简单的平衡树Treap,感觉 ...

  7. httpclient httpcore jar包及源码

    HttpClient HttpCore HttpComponents jar src download httpclient home help

  8. 搜狐畅游CEO王滔辞职

    凤凰科技讯 11月3日消息,搜狐公布公告确认搜狐畅游CEO离职.公告称王滔因个人原因辞去畅游首席运行官职务.将继续担任畅游公司董事和首席产品官. 据搜狐公告,董事会任命搜狐总裁余楚媛与畅游总裁陈德文为 ...

  9. Java中的http(网络处理)相关的库:HttpClient,HttpCore(转载)

    [背景] 最近和之前,折腾了这个: [教程]模拟登陆百度之Java代码版 然后,对于Java的HttpClient,有了点了解. 现在整理如下: Java本身没有Http相关的库 Java本身,没有内 ...

随机推荐

  1. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第二十一章-授予身份与切换身份(二) 1.回顾 ...

  2. 转:maven2创建一个eclipse工程,设置M2_REPO

    from: http://tonychanhoho.iteye.com/blog/1584324 M2_REPO是一个用来定义 maven 2仓库在硬盘中的存储位置,windows默认是C:\User ...

  3. 在cmd窗口输入命令遇到You must run this command from a command prompt with administrator privilege怎么办?

    点开始菜单,找到Accessories(附件),找到Command Prompt窗口,点右键,选“run as administrator”(以管理员身份运行),之后再执行先前的命令就好了. 2017 ...

  4. Kali Linux 2.0安装光盘分享

    Kali Linux 2.0安装光盘分享 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I ...

  5. hdu1394 Minimum Inversion Number(最小逆序数)

    Minimum Inversion Number Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/O ...

  6. 身份证识别接口编写的JAVA调用示例

    此java文章是基本聚合数据证件识别接口来演示,基本HTTP POST请求上传图片并接收JSON数据来处理. 使用前你需要通过 https://www.juhe.cn/docs/api/id/153 ...

  7. UNP学习笔记(第七章 套接字选项)

    有多种方法获取和设置影响套接字的选项: 1.getsockopt和setsockopt函数 2.fcntl函数 3.ioctl函数 getsockopt和setsockopt函数 这两个函数仅用于套接 ...

  8. Log4net日志记录、详细配置(自己使用>)

    log4net库是Apache log4j框架在Microsoft.NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具 1.首先添加对log4net.dll的引 ...

  9. python 中给文件加锁——fcntl模块

    如果没有fcntl模块则用 sudo pip install fcntl安装 模块简单说明: 打开文件,不存在则创建之 f = open('./test','w') fcntl.flock(f,fcn ...

  10. P13在O(1)时间内删除链表结点

    package offer; //在 O(1)时间删除链表结点 public class Problem13 { public static void main(String[] args) { Li ...