zoukankan      html  css  js  c++  java
  • .Net HTTP请求的发送方式与分析

    注:以下内容均来源于网络。

    https://blog.csdn.net/chen213wb/article/details/81747573

    https://blog.csdn.net/qq_23034515/article/details/89226635

    https://www.cjavapy.com/article/50/

    。。。

    HTTP常用请求参数

    Method

    请求方式:Get、Post、Put、Delete

    Timeout

    获取或设置请求的超时值。(毫秒)

    ReadWriteTimeout

    获取或设置读取或写入流时的超时

    KeepAlive

    获取或设置一个值,该值指示是否与 Internet 资源建立持久性连接。

    ClientCertificates

    获取或设置与此请求关联的安全证书集合

    Proxy

    获取或设置请求的代理信息。

    AllowAutoRedirect

    获取或设置一个值,该值指示请求是否应跟随重定向响应。

    CookieContainer

    获取或设置与此请求关联的cookie。

    Credentials

    获取或设置请求的身份验证信息。

    MaximumAutomaticRedirections

    获取或设置请求将跟随的重定向的最大数目。

    SendChunked

    获取或设置一个值,该值指示是否将数据分段发送到 Internet 资源。

    Header.ContentType

    设置请求的数据类型:application/x-www-form-urlencoded、multipart/form-data、application/json、text/xml...

    Header.ContentLength

    设置请求的数据长度

    Header.Accept

    设置响应的数据类型:application/x-www-form-urlencoded、multipart/form-data、application/json、text/xml...

    Header.UserAgent

    客户端的访问类型,包括浏览器版本和操作系统信息

    Header.Referer

    请求的来源地址

    请求方式:

    1、GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改、增加数据,不会影响资源的内容,即该请求不会产生副作用。无论进行多少次操作,结果都是一样的。

    2、与GET不同的是,PUT请求是向服务器端发送数据的,从而改变信息,该请求就像数据库的update操作一样,用来修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次PUT操作,其结果并没有不同。

    3、POST请求同PUT请求类似,都是向服务器端发送数据的,但是该请求会改变数据的种类等资源,就像数据库的insert操作一样,会创建新的内容。几乎目前所有的提交操作都是用POST请求的。

    4、DELETE请求顾名思义,就是用来删除某一个资源的,该请求就像数据库的delete操作。

    就像前面所讲的一样,既然PUT和POST操作都是向服务器端发送数据的,那么两者有什么区别呢?POST主要作用在一个集合资源之上的(url),而PUT主要作用在一个具体资源之上的(url/xxx),通俗一下讲就是,如URL可以在客户端确定,那么可使用PUT,否则用POST。

    综上所述,我们可理解为以下:

    1、GET     /url/xxx  查看

    2、PUT     /url/xxx  更新

    3、POST    /url      创建  

    4、DELETE  /url/xxx  删除  

    数据类型:

    1、application/x-www-form-urlencoded

    浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。

    2、multipart/form-data

    我们使用表单上传文件时,必须让 form 的 enctyped 等于这个值。
    种方式一般用来上传文件时必须使用该种方式,各大服务端语言对它也有着良好的支持。

    3、application/json

    这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。

    4、text/xmlXML-RPC

    协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。 因XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。

    .NET发送HTTP请求的方式

    1、HttpWebRequest

    这是.NET创建者最初开发用于使用HTTP请求的标准类。使用HttpWebRequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是HttpWebRequest类不会阻塞UI线程。例如,当您从响应很慢的API服务器下载大文件时,您的应用程序的UI不会停止响应。HttpWebRequest通常和WebResponse一起使用,一个发送请求,一个获取数据。HttpWebRquest更为底层一些,能够对整个访问过程有个直观的认识,但同时也更加复杂一些。

    这种方法是早期开发者使用的方法,在当前业务中已经很少使用,由于其更加底层,需要处理一些细节,最多用于框架内部操作。

        /// <summary>
        /// 1.通过WebRequest发送请求
        /// </summary>
        public class SendByWebRequest
        {
            public static string Post(string url,string content)
            {
                HttpWebRequest request = null;
                try
                {
                    request = (HttpWebRequest)WebRequest.Create(url);
                    var data = Encoding.UTF8.GetBytes(content);
                    request.Accept = "application/json"; // 设置响应数据的ContentType
                    request.Method = "POST";
                    request.ContentType = "application/json"; // 设置请求数据的ContentType
                    request.ContentLength = data.Length;
                    // 设置入参
                    using (var stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                    // 发送请求
                    var response = (HttpWebResponse)request.GetResponse();
                    // 读取出参
                    using (var resStream = response.GetResponseStream())
                    {
                        using (var reader = new StreamReader(resStream, Encoding.UTF8))
                        {
                            return reader.ReadToEnd();
                        }
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
                finally
                {
                    // 释放连接
                    if (request != null) request.Abort();
                }
            }
    
            public static string Get(string url, string content)
            {
                HttpWebRequest request = null;
                try
                {
                    request = (HttpWebRequest)WebRequest.Create(url + content);
                    request.Accept = "application/json"; // 设置响应数据的ContentType
                    var response = (HttpWebResponse)request.GetResponse();
                    // 读取出参
                    using (var resStream = response.GetResponseStream())
                    {
                        using (var reader = new StreamReader(resStream, Encoding.UTF8))
                        {
                            return reader.ReadToEnd();
                        }
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
                finally
                {
                    // 释放连接
                    if (request != null) request.Abort();
                }
            }
        }

    2、WebClient

    WebClient是一种更高级别的抽象,是HttpWebRequest为了简化最常见任务而创建的,使用过程中你会发现他缺少基本的header,timeoust的设置,不过这些可以通过继承httpwebrequest来实现。相对来说,WebClient比WebRequest更加简单,它相当于封装了request和response方法,不过需要说明的是,Webclient和WebRequest继承的是不同类,两者在继承上没有任何关系。

    使用WebClient可能比HttpWebRequest直接使用更慢(大约几毫秒),但却更为简单,减少了很多细节,代码量也比较少。

    WebClient主要面向了WEB网页场景,在模拟Web操作时使用较为方便,但用在RestFul场景下却比较麻烦,这时候就需要HttpClient出马了。

        /// <summary>
        /// 2.通过WebClient发送请求
        /// </summary>
        public class SendByWebClient
        {
            public static string Post(string url, string content)
            {
                try
                {
                    byte[] para = Encoding.UTF8.GetBytes(content);
                    using (var client = new WebClient())
                    {
                        client.Encoding = Encoding.UTF8;
                        client.Headers.Add("Accept", "application/json"); // 设置响应数据的ContentType
                        client.Headers.Add("Content-Type", "application/json"); // 设置请求数据的ContentType
                        client.Headers.Add("ContentLength", para.Length.ToString());
                        var response = client.UploadData(url, "POST", para);
                        return Encoding.UTF8.GetString(response);
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
    
            public static string Get(string url, string content)
            {
                try
                {
                    using (var client = new WebClient())
                    {
                        client.Encoding = Encoding.UTF8;
                        client.Headers.Add("Accept", "application/json"); // 设置响应数据的ContentType
                        return client.DownloadString(url + content);
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
        }

    3、HttpClient

    目前业务上使用的比较多的是HttpClient,它适合用于多次请求操作,一般设置好默认头部后,可以进行重复多次的请求,基本上用一个实例可以提交任何的HTTP请求。此外,HttpClient提供了异步支持,可以轻松配合async await 实现异步请求。

    HttpClient推荐使用单一实例共享使用,发关请求的方法推荐使用异步的方式。

        /// <summary>
        /// 3.通过HttpClient发送请求
        /// </summary>
        public class SendByHttpClient
        {
            public static string Post(string url, string content)
            {
                try
                {
                    using (HttpClient client = new HttpClient())
                    {
                        
                        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); // 设置响应数据的ContentType
                        var para = new StringContent(content);
                        para.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); // 设置请求数据的ContentType
                        return client.PostAsync(url, para).Result.Content.ReadAsStringAsync().Result;
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
    
            public static string Get(string url, string content)
            {
                try
                {
                    using (HttpClient client = new HttpClient())
                    {
                        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); // 设置响应数据的ContentType
                        return client.GetStringAsync(url + content).Result;
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
    
    
        }

    4、第三方类库

    Flurl.Http,RestSharp等。

        /// <summary>
        /// 4.通过第三方类库发送请求
        /// </summary>
        public class SendByFlurl
        {
            public static string Post(string url, string content)
            {
                try
                {
                    //string abc = $"{url}".PostJsonAsync(content).ReceiveString().Result;
                    return $"{url}".PostAsync(new StringContent(content, Encoding.UTF8, "application/json")).ReceiveString().Result;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
    
            public static string Get(string url, string content)
            {
                try
                {
                    return $"{url}{content}".GetStringAsync().Result;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
        }

    HttpWebRequset

    WebClient

    HttpClient

    命名空间

    System.Net

    System.Net

    System.Net.Http

    继承类

    WebRequest

    Component

    HttpMessageInvoker

    支持url转向

    支持cookie和session

    支持用户代理服务器

    使用复杂度

    扩展

    REST & RPC

      微服务之间的接口调用通常包含两个部分,序列化和通信协议。常见的序列化协议包括json、xml、hession、protobuf、thrift、text、bytes等;通信比较流行的是http、soap、websockect,RPC通常基于TCP实现,常用框架例如dubbo,netty、mina、thrift。

      REST:严格意义上说接口很规范,操作对象即为资源,对资源的四种操作(post、get、put、delete),并且参数都放在URL上,但是不严格的说Http+json、Http+xml,常见的http api都可以称为Rest接口。

      RPC:即我们常说的远程过程调用,就是像调用本地方法一样调用远程方法,通信协议大多采用二进制方式。

    HTTP vs 高性能二进制协议

      HTTP相对更规范,更标准,更通用,无论哪种语言都支持HTTP协议。如果你是对外开放API,例如开放平台,外部的编程语言多种多样,你无法拒绝对每种语言的支持,相应的,如果采用HTTP,无疑在你实现SDK之前,支持了所有语言,所以,现在开源中间件,基本最先支持的几个协议都包含RESTful。

      RPC协议性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能达到http的二倍。响应时间也更为出色。千万不要小看这点性能损耗,公认的,微服务做的比较好的,例如,netflix、阿里,曾经都传出过为了提升性能而合并服务。如果是交付型的项目,性能更为重要,因为你卖给客户往往靠的就是性能上微弱的优势。

      所以,最佳实践一般是对外REST,对内RPC,但是追求极致的性能会消耗很多额外的成本,所以一般情况下对内一般也REST,但对于个别性能要求较高的接口使用RPC。

  • 相关阅读:
    Flink实例(十九):FLINK 异步IO (四)实例 (二) MySQL
    Flink实例(十八):FLINK 异步IO (三)实例 (一)
    Flink实例(十七):FLINK 异步IO (二)原理
    kata镜像
    golang no Go files
    docker命令
    golang 编译安装kata container (二)
    golang代理
    golang 安装依赖
    golang
  • 原文地址:https://www.cnblogs.com/ariter/p/11840243.html
Copyright © 2011-2022 走看看