HttpWebRequest类

HttpWebRequest类与HttpRequest类的区别。

HttpRequest类的对象用于服务器端,获取客户端传来的请求的信息,包括HTTP报文传送过来的所有信息。而HttpWebRequest用于客户端,拼接请求的HTTP报文并发送等。

HttpWebRequest这个类非常强大,强大的地方在于它封装了几乎HTTP请求报文里需要用到的东西,以致于能够能够发送任意的HTTP请求并获得服务器响应(Response)信息。采集信息常用到这个类。在学习这个类之前,首先有必要了解下HTTP方面的知识。

一、简单示例

我们先来一个最简单的,就是紧紧输入一个网址就获取响应。代码如下:

class Program{static void Main(string[] args){HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.baidu.com");    //创建一个请求示例HttpWebResponse response  = (HttpWebResponse)request.GetResponse();  //获取响应,即发送请求Stream responseStream = response.GetResponseStream();StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);string html = streamReader.ReadToEnd();Console.WriteLine(html);Console.ReadKey();}}

OK,就是这么简单了,真的这么简单吗?发送一个HTTP请求真的这么简单。但是要做出很多功能就不简单了。你需要详细了解下HTTP方面的知识,比如HTTP请求报文之类的。

二、模拟登录

下面来个复杂点的,这次是获取登录之后的页面。登录之后的请求用什么实现呢?呵呵,用到是cookie。在拼接HTTP请求的时候,连着cookie也发送过去。

namespace ConsoleApplication1
{class Program{static void Main(string[] args){HttpHeader header = new HttpHeader();header.accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*";header.contentType = "application/x-www-form-urlencoded";header.method = "POST";header.userAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";header.maxTry = 300;//在这里自己拼接一下Cookie,不用复制过来的那个GetCookie方法了,原来的那个写法还是比较严谨的CookieContainer cc = new CookieContainer();Cookie cUserName = new Cookie("cSpaceUserEmail", "742783833%40qq.com");cUserName.Domain = ".7soyo.com";Cookie cUserPassword = new Cookie("cSpaceUserPassWord", "4f270b36a4d3e5ee70b65b1778e8f793");cUserPassword.Domain = ".7soyo.com";cc.Add(cUserName);cc.Add(cUserPassword);string html = HTMLHelper.GetHtml("http://user.7soyo.com/CollectUser/List", cc, header);FileStream fs = new FileStream(@"D:\123.txt",FileMode.CreateNew,FileAccess.ReadWrite);fs.Write(Encoding.UTF8.GetBytes(html),0,html.Length);fs.Flush();fs.Dispose();Console.WriteLine(html);Console.ReadKey();}}public class HTMLHelper{/// <summary>/// 获取CooKie/// </summary>/// <param name="loginUrl"></param>/// <param name="postdata"></param>/// <param name="header"></param>/// <returns></returns>public static CookieContainer GetCooKie(string loginUrl, string postdata, HttpHeader header){HttpWebRequest request = null;HttpWebResponse response = null;try{CookieContainer cc = new CookieContainer();request = (HttpWebRequest)WebRequest.Create(loginUrl);request.Method = header.method;request.ContentType = header.contentType;byte[] postdatabyte = Encoding.UTF8.GetBytes(postdata);     //提交的请求主体的内容request.ContentLength = postdatabyte.Length;    //提交的请求主体的长度request.AllowAutoRedirect = false;request.CookieContainer = cc;request.KeepAlive = true;//提交请求
                Stream stream;stream = request.GetRequestStream();stream.Write(postdatabyte, 0, postdatabyte.Length);     //带上请求主体
                stream.Close();//接收响应response = (HttpWebResponse)request.GetResponse();      //正式发起请求response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);CookieCollection cook = response.Cookies;//Cookie字符串格式string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri);return cc;}catch (Exception ex){throw ex;}}/// <summary>/// 获取html/// </summary>/// <param name="getUrl"></param>/// <param name="cookieContainer"></param>/// <param name="header"></param>/// <returns></returns>public static string GetHtml(string getUrl, CookieContainer cookieContainer, HttpHeader header){Thread.Sleep(1000);HttpWebRequest httpWebRequest = null;HttpWebResponse httpWebResponse = null;try{httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(getUrl);httpWebRequest.CookieContainer = cookieContainer;httpWebRequest.ContentType = header.contentType;httpWebRequest.ServicePoint.ConnectionLimit = header.maxTry;httpWebRequest.Referer = getUrl;httpWebRequest.Accept = header.accept;httpWebRequest.UserAgent = header.userAgent;httpWebRequest.Method = "GET";httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();Stream responseStream = httpWebResponse.GetResponseStream();StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);string html = streamReader.ReadToEnd();streamReader.Close();responseStream.Close();httpWebRequest.Abort();httpWebResponse.Close();return html;}catch (Exception e){if (httpWebRequest != null) httpWebRequest.Abort();if (httpWebResponse != null) httpWebResponse.Close();return string.Empty;}}}public class HttpHeader{public string contentType { get; set; }public string accept { get; set; }public string userAgent { get; set; }public string method { get; set; }public int maxTry { get; set; }}
}

这样获取到的就是登录之后的页面了。

三、模拟表单提交

再来一个例子,运用HttpWebRequest来模拟表单的提交,先新建一个MVC项目,里面只有这些代码:

[HttpPost]
public ActionResult Index(string userName,string userPassword)
{string str = "你提交过来的用户名是:" + userName + ",密码是: " + userPassword;Response.Write(str);return View();
}

然后启动该项目,再新建另外一个项目,用于模拟提交表单,然后注意路径填写的是刚才建的那个MVC项目。

static void Main(string[] args){HttpWebRequest request = null;HttpWebResponse response = null;CookieContainer cc = new CookieContainer();request = (HttpWebRequest)WebRequest.Create("http://localhost:2539/");request.Method = "POST";request.ContentType = "application/x-www-form-urlencoded";request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0";string requestForm = "userName=1693372175&userPassword=123456";     //拼接Form表单里的信息byte[] postdatabyte = Encoding.UTF8.GetBytes(requestForm);request.ContentLength = postdatabyte.Length;request.AllowAutoRedirect = false;request.CookieContainer = cc;request.KeepAlive = true;Stream stream;stream = request.GetRequestStream();stream.Write(postdatabyte, 0, postdatabyte.Length); //设置请求主体的内容
            stream.Close();//接收响应response = (HttpWebResponse)request.GetResponse();Console.WriteLine();Stream stream1 = response.GetResponseStream();StreamReader sr = new StreamReader(stream1);Console.WriteLine(sr.ReadToEnd());Console.ReadKey();}

输出结果如下所示:

四、模拟上传

血的教训,注意路径不能写错,否则在对流进行操作时,Write,就会报错:

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:9170/upload/test"); 

客户端:

class Program{/** * 如果要在客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求 * Content-Type必须是multipart/form-data。 * 以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同 * multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如7d4a6d158c9: * 我们模拟的提交要设定 content-type不同于非含附件的post时候的content-type * 这里需要: ("Content-Type", "multipart/form-data; boundary=ABCD"); * 然后,将每个字段用“--7d4a6d158c9”分隔,最后一个“--7d4a6d158c9--”表示结束。 * 例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下: *  * --7d4a6d158c9 * Content-Disposition: form-data; name="title" * \r\n\r\n * Today * --7d4a6d158c9 * Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt" * Content-Type: text/plain * 如果是图片Content-Type: application/octet-stream * \r\n\r\n * <这里是1.txt文件的内容> * --7d4a6d158c9 * \r\n * 请注意,每一行都必须以\r\n结束value前面必须有2个\r\n,包括最后一行。 */static void Main(string[] args){string boundary = "----------" + DateTime.Now.Ticks.ToString("x");//元素分割标记 StringBuilder sb = new StringBuilder();sb.Append("--" + boundary);sb.Append("\r\n");sb.Append("Content-Disposition: form-data; name=\"file1\"; filename=\"D:\\upload.xml" + "\"");sb.Append("\r\n");sb.Append("Content-Type: application/octet-stream");sb.Append("\r\n");sb.Append("\r\n");//value前面必须有2个换行  
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:9170/upload/test");request.ContentType = "multipart/form-data; boundary=" + boundary;//其他地方的boundary要比这里多--  request.Method = "POST";FileStream fileStream = new FileStream(@"D:\123.xml", FileMode.OpenOrCreate, FileAccess.Read);byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sb.ToString());byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");//http请求总长度  request.ContentLength = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;Stream requestStream = request.GetRequestStream(); requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];int bytesRead = 0;while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0){requestStream.Write(buffer, 0, bytesRead);}fileStream.Dispose();requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);WebResponse webResponse2 = request.GetResponse();Stream htmlStream = webResponse2.GetResponseStream();string HTML = GetHtml(htmlStream, "UTF-8");Console.WriteLine(HTML);htmlStream.Dispose();}}

测试服务器端地址:

public ActionResult Test(){HttpRequest request = System.Web.HttpContext.Current.Request;HttpFileCollection FileCollect = request.Files;if (FileCollect.Count > 0)          //如果集合的数量大于0
            {foreach (string str in FileCollect){HttpPostedFile FileSave = FileCollect[str];  //用key获取单个文件对象HttpPostedFilestring imgName = DateTime.Now.ToString("yyyyMMddhhmmss");string AbsolutePath = FileSave.FileName;FileSave.SaveAs(AbsolutePath);              //将上传的东西保存
                }}return Content("键值对数目:" + FileCollect.Count);}

 

转载于:https://www.cnblogs.com/a-dou/p/5755229.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418185.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

比较创建几种线程的方式

JDK5.0新增的创建多线程的方式&#xff1a; 新增一&#xff1a; //创建多线程的方式三&#xff1a;callabe;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask;//1.创建一个Callable的实现类 c…

线程的安全问题

解决方法一: 注意:在synchronized中的同步监视器&#xff08;锁&#xff09;只能是唯一的。 方式二&#xff0c;同步方法 方法三&#xff1a; lock() lock锁 public class ThreadTest6 {public static void main(String[] args) {Window w new Window();Thread t1 new Thre…

数据的个人视角:数据可视化的意义

当谈论到数据可视化对个人用户的实用价值时&#xff0c;很多人可能会想到它仅适用于企业或专业领域。然而&#xff0c;数据可视化对个人用户同样具有重要的实用价值。本文将从可视化从业者的角度出发&#xff0c;简单说说数据可视化对个人用户的实用价值。 首先&#xff0c;数…

线程的通信

//线程通信 //线程1 线程2 交替打印1——100 //wait()和notify()方法需要在一个监视器的同步代码块 中或者是同一个同步方法中// wait()&#xff1a;线程从运行状态进入阻塞状态&#xff0c;并且释放锁 // notify():一旦执行此方法就会唤醒被wait的一个线程&#xff0c;如果多个…

线程通信的经典问题:生产者消费者问题

package ThreadTest2; // 线程通信的经典问题&#xff1a;生产者消费者//店员&#xff08;资源&#xff09; class Clerk{private int productCount 0 ;public synchronized void produceProduct() {if(productCount < 100 ) {productCount;System.out.println(Thread.curr…

String类中不同拼接方式

有变量名参与都不是在常量池中了&#xff0c;类似于new

使用JMeter创建数据库(Mysql)测试

我的环境&#xff1a;MySQL&#xff1a;mysql-essential-5.1.51-win32 jdbc驱动&#xff1a;我已经上传到csdn上一个&#xff1a;http://download.csdn.net/source/3451945 JMeter&#xff1a;jmeter-2.4 任意版本都行。 1.首先我们要有一个可以做测试的数据库&#xff0c;当然…

String类与其他数据类型得转换

一&#xff1a;与基本数据类型或者包装类 二、String与char型数组得转换 三、String类与字节数组byte[]之间的转换 输出的是字符中得ASCII码。 getBytes使用的默认得编码集 可以自主设置编码集否则为默认编码集 输出&#xff1a;

字符串类中的StringBuffer,StringBuilder

StringBuffer类的常用方法 &#xff0c; String StringBuffer,StringBuilder的效率

JAVA日期和时间API

JDK8以前&#xff1a; public void test2() { // 构造器1&#xff1a;Date date1 new Date();System.out.println(date1); // date1.toString// 构造器2&#xff1a;创建指定毫秒数的Date对象Date date2 new Date(1631722133700L);System.out.println(date2);} JDK8以后: …

Calender日历类

使用方法&#xff1a; Testpublic void test() { // 调用其静态方法得到一个对象Calendar calendar Calendar.getInstance();System.out.println(calendar.getClass()); // 输出的为 GregorianCalendar类// get() 得到所需的数据 比如这一年的第几天int days calendar.…

JDK8后的日期时间API

Testpublic void test() { // now() 获取当前的时间&#xff0c;日期LocalDate ld LocalDate.now();LocalTime lt LocalTime.now();LocalDateTime ldt LocalDateTime.now();System.out.println(ld);System.out.println(lt);System.out.println(ldt);// of():指定年月日 …

送花(洛谷 2073)

题目背景 小明准备给小红送一束花&#xff0c;以表达他对小红的爱意。他在花店看中了一些花&#xff0c;准备用它们包成花束。 题目描述 这些花都很漂亮&#xff0c;每朵花有一个美丽值W&#xff0c;价格为C。 小明一开始有一个空的花束&#xff0c;他不断地向里面添加花。他有…