C#中HttpWebRequest、WebClient、HttpClient的使⽤详解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和res
ponse⽅法,不过需要说明的是,Webclient和WebRequest继承的是不同类,两者在继承上没有任何关系。使⽤WebClient可能⽐HttpWebRequest直接使⽤更慢(⼤约⼏毫秒),但却更为简单,减少了很多细节,代码量也⽐较少。
1
2
3
4
5 6 7 8 9 10 11 12 13 14 15 16public 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");
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 4
8 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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 11public 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 7public 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 14public class Singleton {
private volatile static Singleton singleton; private Singleton (){}
public static Singleton getSingleton() { if(singleton == null) {
synchronized (Singleton.class) {
java单例模式懒汉和饿汉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 22public 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();
}
}
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 }
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/js
on"); //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_httpClient = new HttpClient() { BaseAddress = new Uri(BASE_ADDRESS) }; //帮HttpClient热⾝
_httpClient.SendAsync(new HttpRequestMessage {
Method = new HttpMethod("HEAD"),
6 7 RequestUri = new Uri(BASE_ADDRESS + "/") }) .Result.EnsureSuccessStatusCode();
三者区别列表:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论