HttpWebRequest:
命名空间: System.Net,这是.NET创建者最初开发用于使用HTTP请求的标准类。使用HttpWebRequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是HttpWebRequest类不会阻塞UI线程。例如,当您从响应很慢的API服务器下载大文件时,您的应用程序的UI不会停止响应。HttpWebRequest通常和WebResponse一起使用,一个发送请求,一个获取数据。HttpWebRquest更为底层一些,能够对整个访问过程有个直观的认识,但同时也更加复杂一些。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
//POST方法
public
static
string
HttpPost(
string
Url,
string
postDataStr)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method =
"POST"
;
request.ContentType =
"application/x-www-form-urlencoded"
;
Encoding encoding = Encoding.UTF8;
byte
[] postData = encoding.GetBytes(postDataStr);
request.ContentLength = postData.Length;
Stream myRequestStream = request.GetRequestStream();
myRequestStream.Write(postData, 0, postData.Length);
myRequestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader =
new
StreamReader(myResponseStream, encoding);
string
retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return
retString;
}
//GET方法
public
static
string
HttpGet(
string
Url,
string
postDataStr)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr ==
""
?
""
:
"?"
) + postDataStr);
request.Method =
"GET"
;
request.ContentType =
"text/html;charset=UTF-8"
;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader =
new
StreamReader(myResponseStream, Encoding.GetEncoding(
"utf-8"
));
string
retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return
retString;
}
|
WebClient:
命名空间System.Net,WebClient是一种更高级别的抽象,是HttpWebRequest为了简化最常见任务而创建的,使用过程中你会发现他缺少基本的header,timeoust的设置,不过这些可以通过继承httpwebrequest来实现。相对来说,WebClient比WebRequest更加简单,它相当于封装了request和response方法,不过需要说明的是,Webclient和WebRequest继承的是不同类,两者在继承上没有任何关系。使用WebClient可能比HttpWebRequest直接使用更慢(大约几毫秒),但却更为简单,减少了很多细节,代码量也比较少。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
public
class
WebClientHelper
{
public
static
string
DownloadString(
string
url)
{
WebClient wc =
new
WebClient();
//wc.BaseAddress = url; //设置根目录
wc.Encoding = Encoding.UTF8;
//设置按照何种编码访问,如果不加此行,获取到的字符串中文将是乱码
string
str = wc.DownloadString(url);
return
str;
}
public
static
string
DownloadStreamString(
string
url)
{
WebClient wc =
new
WebClient();
wc.Headers.Add(
"User-Agent"
,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
);
Stream objStream = wc.OpenRead(url);
StreamReader _read =
new
StreamReader(objStream, Encoding.UTF8);
//新建一个读取流,用指定的编码读取,此处是utf-8
string
str = _read.ReadToEnd();
objStream.Close();
_read.Close();
return
str;
}
public
static
void
DownloadFile(
string
url,
string
filename)
{
WebClient wc =
new
WebClient();
wc.DownloadFile(url, filename);
//下载文件
}
public
static
void
DownloadData(
string
url,
string
filename)
{
WebClient wc =
new
WebClient();
byte
[] bytes = wc.DownloadData(url);
//下载到字节数组
FileStream fs =
new
FileStream(filename, FileMode.Create);
fs.Write(bytes, 0, bytes.Length);
fs.Flush();
fs.Close();
}
public
static
void
DownloadFileAsync(
string
url,
string
filename)
{
WebClient wc =
new
WebClient();
wc.DownloadFileCompleted += DownCompletedEventHandler;
wc.DownloadFileAsync(
new
Uri(url), filename);
Console.WriteLine(
"下载中。。。"
);
}
private
static
void
DownCompletedEventHandler(
object
sender, AsyncCompletedEventArgs e)
{
Console.WriteLine(sender.ToString());
//触发事件的对象
Console.WriteLine(e.UserState);
Console.WriteLine(e.Cancelled);
Console.WriteLine(
"异步下载完成!"
);
}
public
static
void
DownloadFileAsync2(
string
url,
string
filename)
{
WebClient wc =
new
WebClient();
wc.DownloadFileCompleted += (sender, e) =>
{
Console.WriteLine(
"下载完成!"
);
Console.WriteLine(sender.ToString());
Console.WriteLine(e.UserState);
Console.WriteLine(e.Cancelled);
};
wc.DownloadFileAsync(
new
Uri(url), filename);
Console.WriteLine(
"下载中。。。"
);
}
}
|
HttpClient:
HttpClient是.NET4.5引入的一个HTTP客户端库,其命名空间为 System.Net.Http ,.NET 4.5之前我们可能使用WebClient和HttpWebRequest来达到相同目的。HttpClient利用了最新的面向任务模式,使得处理异步请求非常容易。它适合用于多次请求操作,一般设置好默认头部后,可以进行重复多次的请求,基本上用一个实例可以提交任何的HTTP请求。HttpClient有预热机制,第一次进行访问时比较慢,所以不应该用到HttpClient就new一个出来,应该使用单例或其他方式获取HttpClient的实例
单例模式:
单例模式(Singleton Pattern)这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例创建步骤:1、定义静态私有对象;2、定义私有构造函数;3、提供公共获取对象方法;
单例模式一般分为两种实现模式:懒汉模式、饿汉模式(以下为Java代码实现)
懒汉模式: 默认不会实例化,什么时候用什么时候new
1
2
3
4
5
6
7
8
9
10
11
|
public
class
Singleton {
private
static
Singleton instance =
null
;
private
Singleton (){}
public
static
Singleton getInstance() {
if
(instance ==
null
) {
instance =
new
Singleton();
}
return
instance;
}
}
|
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
饿汉模式: 类初始化时,会立即加载该对象,线程天生安全,调用效率高
1
2
3
4
5
6
7
|
public
class
Singleton {
private
static
Singleton instance =
new
Singleton();
private
Singleton (){}
public
static
Singleton getInstance() {
return
instance;
}
}
|
双检锁/双重校验锁(DCL,即 double-checked locking):这种方式采用双锁机制,安全且在多线程情况下能保持高性能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
class
Singleton {
private
volatile
static
Singleton singleton;
private
Singleton (){}
public
static
Singleton getSingleton() {
if
(singleton ==
null
) {
synchronized (Singleton.
class
) {
if
(singleton ==
null
) {
singleton =
new
Singleton();
}
}
}
return
singleton;
}
}
|
HttpClient:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
public
class
HttpClientHelper
{
private
static
readonly
object
LockObj =
new
object
();
private
static
HttpClient client =
null
;
public
HttpClientHelper() {
GetInstance();
}
public
static
HttpClient GetInstance()
{
if
(client ==
null
)
{
lock
(LockObj)
{
if
(client ==
null
)
{
client =
new
HttpClient();
}
}
}
return
client;
}
public
async Task<
string
> PostAsync(
string
url,
string
strJson)
//post异步请求方法
{
try
{
HttpContent content =
new
StringContent(strJson);
content.Headers.ContentType =
new
System.Net.Http.Headers.MediaTypeHeaderValue(
"application/json"
);
//由HttpClient发出异步Post请求
HttpResponseMessage res = await client.PostAsync(url, content);
if
(res.StatusCode == System.Net.HttpStatusCode.OK)
{
string
str = res.Content.ReadAsStringAsync().Result;
return
str;
}
else
return
null
;
}
catch
(Exception ex)
{
return
null
;
}
}
public
string
Post(
string
url,
string
strJson)
//post同步请求方法
{
try
{
HttpContent content =
new
StringContent(strJson);
content.Headers.ContentType =
new
System.Net.Http.Headers.MediaTypeHeaderValue(
"application/json"
);
//client.DefaultRequestHeaders.Connection.Add("keep-alive");
//由HttpClient发出Post请求
Task<HttpResponseMessage> res = client.PostAsync(url, content);
if
(res.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
string
str = res.Result.Content.ReadAsStringAsync().Result;
return
str;
}
else
return
null
;
}
catch
(Exception ex)
{
return
null
;
}
}
public
string
Get(
string
url)
{
try
{
var responseString = client.GetStringAsync(url);
return
responseString.Result;
}
catch
(Exception ex)
{
return
null
;
}
}
}
|
HttpClient有预热机制,第一次请求比较慢;可以通过初始化前发送一次head请求解决:
1
2
3
4
5
6
7
|
_httpClient =
new
HttpClient() { BaseAddress =
new
Uri(BASE_ADDRESS) };
//帮HttpClient热身
_httpClient.SendAsync(
new
HttpRequestMessage {
Method =
new
HttpMethod(
"HEAD"
),
RequestUri =
new
Uri(BASE_ADDRESS +
"/"
) })
.Result.EnsureSuccessStatusCode();
|
三者区别列表:
出处:https://www.cnblogs.com/nnnnnn/p/13509169.html
=======================================================================================
WebClient, HttpClient, HttpWebRequest ,RestSharp之间的区别
NETCore提供了三种不同类型用于生产的REST API: HttpWebRequest;
WebClient;
HttpClient
,开源社区创建了另一个名为RestSharp的库
。如此多的http库,该怎样选择呢?
HttpWebRequest
这是.NET创建者最初开发用于使用HTTP请求的标准类。使用HttpWebRequest可以让开发者控制
请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是HttpWebRequest
类不会阻塞UI线程。例如,当您从响应很慢的API服务器下载大文件时,您的应用程序的UI不会停止响应。
然而,强大的个性化操作带来了极大的复杂性。为了简单起见,GET
您需要至少五行代码;
HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://example.com"); WebResponse response = http.GetResponse(); Stream stream = response.GetResponseStream(); using (var streamtemn = File.Create("路径")) { stream.CopyTo(streamtemn); }
如果对http协议不是了如指掌,使用HttpWebRequest会增加你的开发成本,除非你需要非常细节的处理和底层的控制,另外HttpWebRequest库已经过时,不适合业务中直接使用,他更适用于框架内部操作。
WebClient
WebClient
是一种更高级别的抽象,是HttpWebRequest
为了简化最常见任务而创建的,使用过程中你会发现他缺少基本的header,timeoust的设置,不过这些可以通过继承httpwebrequest来实现。使用WebClient
可能比HttpWebRequest
直接使用更慢(大约几毫秒)。但这种“低效率”带来了巨大的好处:它需要更少的代码和隐藏了细节处理,更容易使用,并且在使用它时你不太可能犯错误。同样的请求示例现在很简单只需要两行而且内部周到的处理完了细节:
using (WebClient webClient = new WebClient()) { webClient.DownloadFile("http://example.com", "路径"); }
HttpClient
HttpClient
提供强大的功能,提供了异步支持,可以轻松配合async await 实现异步请求,具体使用可参考:NetCore 2.1中的HttpClientFactory最佳实践
RestSharp
restsharp是开源社区贡献,具有HttpWebRequest的细节控制和WebClient的使用简单的优点从而让他功能强大的同时又简化了操作(从他定义的接口可以看出真是一个优秀的http库啊😊)
结论
HttpWebRequest
已经不推荐直接使用了,这已经作为底层机制,不适合业务代码使用WebClient
不想为http细节处理而头疼的coder而生,由于内部已经处理了通用设置,某些情况可能导致性能不是很理想RestSharp
兼具强大功能和友好api很适合业务中使用HttpClient
更加适用于异步编程模型中
参考:
https://stackoverflow.com/questions/22791376/is-httpwebrequest-or-webclient-faster/22792326#22792326
https://stackoverflow.com/questions/20530152/deciding-between-httpclient-and-webclient
https://social.msdn.microsoft.com/Forums/vstudio/en-US/2ce80a71-1ced-4bcd-adb4-88eef6e6a42d/httpclient-vs-httpwebrequest?forum=wcf
https://stackify.com/restsharp/?utm_referrer=https%3A%2F%2Fwww.google.com%2F
=======================================================================================
.NET中 HttpWebRequest、 WebClient 、 HttpClient 的区别
1、HttpWebRequest
这是.NET创建者最初开发用于使用HTTP请求的标准类。使用HttpWebRequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是HttpWebRequest类不会阻塞UI线程。例如,当您从响应很慢的API服务器下载大文件时,您的应用程序的UI不会停止响应。
如果对http协议不是了如指掌,使用HttpWebRequest会增加你的开发成本,除非你需要非常细节的处理和底层的控制,另外HttpWebRequest库已经过时,不适合业务中直接使用,他更适用于框架内部操作。
创建HttpWebRequest实例时,使用WebRequest.Create方法。如果统一资源标示符的方案是http://或https://,则Create返回HttpWebRequest对象。
GetResponse方法向RequestUri属性中指定的资源发送同步请求,并返回包含该响应的HttpWebResponse。
可以使用BeginGetResponse和EndGetResponse方法对资源发出异步请求.
当想要资源发送数据时,GetRequestStream方法返回用于发送数据的Stream对象。BeginGetRequestStream和EndGetRequestStream方法提供发送数据流的异步访问。
发送Get请求
//建立请求
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("");
//发送请求获取Http响应
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
//获取响应流
Stream receiveStream = response.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
Console.WriteLine(reader.ReadToEnd());
发送Post请求
public static void Main()
{
//建立请求
HttpWebRequest request=(HttpWebRequest)WebRequest.Create("");
request.Method="Post";
string inputData=Console.ReadLine();
string postData="firstnone="+inputData;
ASCIIEncoding encoding = new ASCIIEncoding ();
byte[] byte1=encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
Stream newStream = request.GetRequestStream ();
newStream.Write (byte1, 0, byte1.Length);
HttpWebResponse response=(HttpWebResponse)request.GetResponse();
Stream myStream = HttpResp.GetResponseStream();
StreamReader reader = new StreamReader(myStream, code);
}
2、WebClient
WebClient是一种更高级别的抽象,是HttpWebRequest为了简化最常见任务而创建的,使用过程中你会发现他缺少基本的header,timeoust的设置,不过这些可以通过继承httpwebrequest来实现。使用WebClient可能比HttpWebRequest直接使用更慢(大约几毫秒)。但这种“低效率”带来了巨大的好处:它需要更少的代码和隐藏了细节处理,更容易使用,并且在使用它时你不太可能犯错误。同样的请求示例现在很简单只需要两行而且内部周到的处理完了细节:
using (WebClient webClient = new WebClient())
{
webClient.DownloadFile("http://example.com", "路径");
}
附一个简单的Post请求代码示例:
WebClient webClient = new WebClient();
// 向服务器发送POST数据
byte[] responseArray = webClient.UploadValues(url, postValues);
string response = Encoding.UTF8.GetString(responseArray);
returns = response;
3、HttpClient
HttpClient是.NET4.5引入的一个HTTP客户端库,其命名空间为System.Net.Http。.NET 4.5之前我们可能使用WebClient和HttpWebRequest来达到相同目的。但是有几点值得关注: 可以使用单个HttpClient实例发任意数目的请求
一个HttpClient实例不会跟某个HTTP服务器或主机绑定,也就是说我们可以用一个实例同时给www.a.com和www.b.com发请求
可以继承HttpClient达到定制目的
HttpClient利用了最新的面向任务模式,使得处理异步请求非常容易.
知识点整理:
1、为了获得HttpConet对象中的数据,在本例中使用了Result属性,调用Result会阻塞该调用。还可以使用ReadAsStringAsync方法,这是一个异步调用。
2、Http的DefaultRequestHeaders属性允许设置或该变标题,使用Add属性可以给集合添加标题。设置标题后标题与标题值会与这个HttpClient实例发送的每个请求一起发送。
3、HttpClient可以把HttpMessageHandler作为其构造函数的参数,这样就可以定制请求。可以传递HttpClientHandler的实例。它有许多属性可以设置,如ClientCertificates、ContinueTimeout等。
代码实例(Post异步请求)
using (var client = new HttpClient(handler))
{
action = action.TrimEnd();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
header = ApiHeaderCompent.AddHeader(requestUri, action, body, header,
HttpMethod.Post, appContext, context);
header?.ForEach(p => client.DefaultRequestHeaders.Add(p.Key, p.Value));
result = client.PostAsJsonAsync(requestUri + action, body).Result;
if (!result.IsSuccessStatusCode)
throw new Exception($"API POST 请求失败,请求地址: {requestUri + action}");
var data = JsonConvert.DeserializeObject<T>(result.Content.ReadAsStringAsync().Result);
return new ApiResult<T>(data);
}
出处:https://blog.csdn.net/u012482453/article/details/105659161/
=======================================================================================
=======================================================================================