当前位置: 首页 > 编程笔记 >

完成OSS.Http底层HttpClient重构封装 支持标准库

宗政鸿志
2023-03-14
本文向大家介绍完成OSS.Http底层HttpClient重构封装 支持标准库,包括了完成OSS.Http底层HttpClient重构封装 支持标准库的使用技巧和注意事项,需要的朋友参考一下

OSS.Http项目对于.Net Standard标准库的支持已经迁移完毕,OSS开源系列两个最底层的类库已经具备跨运行时支持的能力。由于OSS.Http类库是几年前我参照RestSharp的思路,完成的一个轻量型Http请求框架。因为时间较久底层使用的还是HttpWebRequest,这次基本上是完全重构,这篇文章主要包含 1. HttpClient的介绍,2. 重构的思路, 3. 容易遇到的问题。

一. httpclient的基本介绍

HttpClient应该是在.net framework4.5版本左右引用的新功能,在此之前常用的是HttpWebRequest,相比较而言,前者更加的简单清晰,最重要的是完全支持.net standard API,这也是我选择它的重要原因。

HttpClient在结构上做了很大的调整,并且是完全异步的实现,可以说从底层上完成了异步的支持,这里先介绍对应的几个主要类:

1.  HtttpRequestMessage

请求的基本信息,请求地址,请求动作等,此值是在HttpClient发起请求的方法中当参数传入,与他对应的是响应 HttpResponseMessage

2.  HttpContent

请求的内容体,主要包含请求的具体内容,contenttype,contentlenght等,是HtttpRequestMessage的一个属性,这两个都包含Headers属性,但是范围分别不一样,这个是很容易混淆出错的地方,我给做了简单分类:

HttpRequestMessage的头部(HttpRequestHeaders )主要是请求的属性,如Accept,UserAgent,AcceptEncoding等http链接的基本属性。

HttpContent的头部(HttpContentHeaders)主要是当前请求内容的属性,主要有:Allow,Content-Encoding,Content-Length,Content-Type ,Expires ,Last-Modified 等,详见官方类库。

HttpContent 系统提供了几个默认实现,主要如下几个:

3.  HttpMessageHandler

此类主要作用是请求内容处理动作等的定义,如是否支持重定向,是否可以使用cookie,代理Proxy等,偏向于系统的设置,可以此值通过HttpClient构造函数传入其中,系统默认的提供的子类为HttpClientHandler。

4.  HttpClient

具体的请求实现调用实现,完整实现了POST,GET,Delete等Http请求方法,所有的方法最终调用的是SendAsync方法。

上边的四个主要类,构成了HttpClient请求的主要实现,如果你只是简单的使用,那么只需要关心HttpClient即可,如下:

其实在它内部已经默认实现了HttpRequestMessage和HttpClientHandler的赋值。

虽然简单介绍,但是基本上可以看出,HttpClient的实现做了非常明确的分工,不是再像以前所有的设置都集中在webrequest中。分工的明确最直接的优势是HttpClient实现了多请求共用,参见博文:

The default HttpClient is the simplest way in which you can start sending requests. A single HttpClient can be used to send as many HTTP requests as you want concurrently so in many scenarios you can just create one HttpClient and then use that for all your requests.

也就是当你系统中要发起不同的请求时,可以共用一个HttpClient,而不用像HttpWebReqest基本每次请求都需要重新定义一个对象,以减少资源的消耗。

二. 重构OSS.Http

  回到正题,重构我们的当前代码模块,如我所说,由于.Net Standard下完全不提供httpWebRequest的支持,直接导致了我做出重新实现的决定,因为以前httpWebRequest的简陋,所以我基本上做了很大的封装框架,上层完全不需要接触具体的底层实现,基本上实现了RestSharp的核心,有兴趣的同学可以参考代码 OSS.Http 下Old分支。

  重构之前由于对HttpClient不是十分了解,本想延续已有框架流程,转换实现。不过随着对Client文档的查看研究,发现很多封装已经完全不需要,流程也发生了变化,所以删除很多原来框架下的东西,重新整理出最终的实现。

  当然现在的HttpClient本身实现已经足够简单清晰,不过在很多情况下直接调用POST,GET等方法,会减少部分代码的重用,像在OSS.Social项目中,底层我只需要实现一个RestCommon方法,即可达到全局请求控制,调用方只需要提供Url,HttpMothed,Parameter即可。

  这里我画了一个简单的流程图作为呈现:

流程基本没有太大的出入,代码在Github,文件的结构如下:

  Mos文件下: Enum.cs  枚举类,FileParameter.cs 文件参数类,FormParameter Form表单参数类 ,OsHttpRequest 请求参数类,

  OsRest.cs  是当前封装类的主要实现,同时为了保证HttpClient本身功能通用,OsRest继承自HttpClient,同时提供了RestSend方法,在这个方法中完成流程的实现并最终调用SendAsync方法执行请求。

  RestUtil.cs  辅助类,完成了全局OsRest(HttpClient)的共用,并定义了一个默认HttpClientHandler实现,正常直接调用这个类就可以了。

  流程中的执行用户自定义设置,可以在OSHttpRequest中的RequestSet委托属性中设置,例如可以设置访问类型是json:

三.  容易遇到的问题

  虽然整个重构后的代码已经不多了,但是应该还是有些问题可以给大家分享下

  1.  Header赋值问题,请参见我第一部分,一定要分清不同Headers,否则就可能给你报不正确的值错误

  2.  可以发现上边的流程图中有个“是否是Get”的判断,因为如果是Get请求,Content是不能赋值的,就像在HttpWebReqest中,如果get请求调用了GetRequestStream方法,会有“无法发送具有此谓词类型的内容正文”的异常错误。当然如果你使用的是OSS.Http作为请求,那么就没有这个问题了。

  3.  和上传文件同时上传的表单参数,与单独的表单参数提交,是不一样的,请注意处理,不懂得参见OsRest类即可,已经做了处理。

如果你还有其他问题,或者对后续的更新感兴趣,请关注公众号(OSSCoder):

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!

 类似资料:
  • 主要内容:Java11 标准HttpClient,Java11 使用 HttpClient 的步骤,Java11 使用 HttpClient的示例Java11 标准HttpClient Java 9 中引入了增强的 HttpClient API 作为实验性功能。在 Java 11 中,现在 HttpClient 是一个标准。建议使用 Apache Http Client API 等其他 HTTP Client API 代替。它的功能非常丰富,现在基于 Java 的应用程序可以在不使用任何外部依赖

  • 本文向大家介绍Python底层封装实现方法详解,包括了Python底层封装实现方法详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Python底层封装实现方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 事实上,python封装特性的实现纯属“投机取巧”,之所以类对象无法直接调用私有方法和属性,是因为底层实现时,python

  • Angular的i18n很棒,像ng-packagr这样的工具使组件库打包变得极其容易,但是它们能结合起来吗? 如果我想打包和分发一个具有可翻译组件的组件库,该怎么办?有可能吗?我如何包装这样的库?翻译文件会随包一起出货吗,还是应该在主App中定义? 如果有人能给我指个医生就好了。谢谢

  • 本文向大家介绍Bootstrap被封装的弹层,包括了Bootstrap被封装的弹层的使用技巧和注意事项,需要的朋友参考一下 对于Bootstrap的弹层,插件有很多,今天主要用的是它自带的功能,通过bootstrap提供的模式窗口来实现的,而小编主要对使用方法进行了封装,开发人员可以自己动态传入弹层的HTML内容,可以控制按钮的显示与隐藏,用户通过MVC扩展方法对弹层进行生成,然后使用A标签进行调

  • [source] TimeDistributed keras.layers.TimeDistributed(layer) 这个封装器将一个层应用于输入的每个时间片。 输入至少为 3D,且第一个维度应该是时间所表示的维度。 考虑 32 个样本的一个 batch, 其中每个样本是 10 个 16 维向量的序列。 那么这个 batch 的输入尺寸为 (32, 10, 16), 而 input_shap

  • 问题内容: 库Apache Commons HttpClient是否支持Gzip?我们想在Apache服务器上使用enable gzip压缩来加速客户端/服务器通信(我们有一个php页面,允许我们的Android应用程序与服务器同步文件)。 问题答案: Apache HttpClient 4.1支持现成的内容压缩以及以前认为超出范围的许多其他功能。