HttpURLConnection模拟浏览器http请求【转】
本文是参考网络文章测试整理,报歉忘记参考地址了,这只是做参考
1 import java.io.BufferedReader; 2 import java.io.DataOutputStream; 3 import java.io.InputStreamReader; 4 import java.net.HttpURLConnection; 5 import java.net.URL; 6 import java.net.URLEncoder; 7 8 /** 9 * HttpURLConnection 模拟浏览器http请求处理测试 10 * 11 * 整体操作流程(注意顺序) 12 * 1.根据url地址创建URL对象 13 * 2.url.openConnection() 得到HttpURLConnection 14 * 3.设置HttpURLConnection的配置(会根据配置生成http请求头信息) 15 * 4.httpConn.connect()建立与服务器的TCP连接 16 * 5.通过httpConn得到输出流,并写入参数 17 * 6.通过httpConn得到输入流,并读取服务器返回信息(这时才真正产生http请求发送给服务器,但可以根据配置来改变;一般返回可能是html字符串) 18 * 19 * httpRequestPost/httpRequestGet两种方式测试通过,返回的是html字符串(后台是jsp) 20 * 21 */ 22 public class HttpURLConnectionTest { 23 24 public static void main(String[] strs) throws Exception{ 25 HttpURLConnectionTest t = new HttpURLConnectionTest(); 26 String url = "http://localhost:8080/URLTest/filesystem/fileBrowse.do"; 27 t.httpUrlConnection(url); 28 } 29 30 private void httpUrlConnection(String urlStr) throws Exception{ 31 httpRequestGet(urlStr); 32 httpRequestPost(urlStr); 33 } 34 35 /** 36 * http post请求 37 * @param urlStr URL地址 38 * @throws Exception 39 */ 40 private void httpRequestPost(String urlStr) throws Exception{ 41 URL url = new URL(urlStr); 42 43 HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); 44 45 //设置是否向connection输出,因为是post请求,参数要放在 http正文内,因此需要设为true 46 httpConn.setDoOutput(true); 47 48 //是否向connection输入,默认为true 49 httpConn.setDoInput(true); 50 51 //POST请求方式 52 httpConn.setRequestMethod("POST"); 53 54 //post请求不能使用缓存 55 httpConn.setUseCaches(false); 56 57 //是否自动执行重定向,默认为true 58 httpConn.setInstanceFollowRedirects(true); 59 60 //配置本次连接的Content-type,配置为application/x-www-form-urlencoded的意思是正文是urlencoded编码过的form参数 61 //下面我们可以看到我们对正文内容使用URLEncoder.encode 进行编码 62 httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 63 64 //连接,从openConnection()至此的配置必须要在connect之前完成, 注意的是connection.getOutputStream会隐含的进行connect。 65 httpConn.connect(); 66 67 DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream()); 68 69 //发送正文,正文内容其实跟get的URL中'?'后的参数字符串一致 word=wait&tn=news&from=news 70 String content = "filePath=" + URLEncoder.encode("设计资料/设计", "utf-8"); 71 72 //DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面 73 dos.writeBytes(content); 74 75 //刷新流 76 dos.flush(); 77 78 //关闭流 79 dos.close(); 80 81 // 取得输入流,并使用Reader读取 82 BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); 83 84 System.out.println("=========post request接收数据内容开始============"); 85 String lines; 86 while ((lines = reader.readLine()) != null) { 87 System.out.println(lines); 88 } 89 reader.close(); 90 System.out.println("=========post request接收数据内容结束============"); 91 httpConn.disconnect(); 92 } 93 94 /** 95 * http get 请求 96 * @param urlStr 请求URL地址 97 * @throws Exception 98 */ 99 private void httpRequestGet(String urlStr) throws Exception{ 100 //URL拼接,如:"http://www.baidu.com?name=HI,中国",这里对特殊字符进行了编码,不然会产生乱码 101 URL url = new URL(urlStr + "?filePath=" + URLEncoder.encode("设计资料/设计", "utf-8")); 102 103 //openConnection函数会根据URL的协议返回不同的URLConnection子类的对象 104 //这里URL是一个http,因此实际返回的是HttpURLConnection 105 HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); 106 107 //进行连接,实际上request要在下一句的connection.getInputStream()函数中才会真正发到 服务器****待验证 108 httpConn.connect(); 109 110 // 取得输入流,并使用Reader读取 111 BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); 112 113 System.out.println("=========get request接收数据内容开始============"); 114 String lines; 115 while ((lines = reader.readLine()) != null) { 116 System.out.println(lines); 117 } 118 reader.close(); 119 System.out.println("=========get request接收数据内容结束============"); 120 httpConn.disconnect(); 121 } 122 123 124 /** 125 * http post 请求(未测试) 126 * 127 * @param urlStr 128 * @throws Exception 129 */ 130 public static void httpRequestPostBig(String urlStr) throws Exception { 131 URL postUrl = new URL(urlStr); 132 HttpURLConnection connection = (HttpURLConnection) postUrl 133 .openConnection(); 134 connection.setDoOutput(true); 135 connection.setDoInput(true); 136 connection.setRequestMethod("POST"); 137 connection.setUseCaches(false); 138 connection.setInstanceFollowRedirects(true); 139 connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); 140 //与httpRequestPost()的不同,设置了块大小为5字节 141 connection.setChunkedStreamingMode(5); 142 connection.connect(); 143 /* 144 * 注意,下面的getOutputStream函数工作方式于在httpRequestPost()里面的不同 145 * 在httpRequestPost()里面该函数仍在准备http request,没有向服务器发送任何数据 146 * 而在这里由于设置了ChunkedStreamingMode,getOutputStream函数会根据connect之前的配置 147 * 生成http request头,先发送到服务器。 148 */ 149 DataOutputStream out = new DataOutputStream(connection 150 .getOutputStream()); 151 String content = "name=" + URLEncoder.encode("发送到服务器 " + 152 " " + 153 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "utf-8"); 154 out.writeBytes(content); 155 156 out.flush(); 157 out.close(); //到此时服务器已经收到了完整的http request了,而在httpRequestPost()函数里,要等到下一句getInputStream()服务器才能收到http请求。 158 BufferedReader reader = new BufferedReader(new InputStreamReader( 159 connection.getInputStream())); 160 161 out.flush(); 162 out.close(); 163 String line; 164 System.out.println("==========post request开始=========="); 165 while ((line = reader.readLine()) != null) { 166 System.out.println(line); 167 } 168 System.out.println("==========post request结束=========="); 169 reader.close(); 170 connection.disconnect(); 171 } 172 }
HttpURLConnection.connect函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection.getInputStream()这个函数里
面才正式发送出去。
在httpRequestPost() 中,顺序很重要,对connection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。而对 outputStream的写操作,又必须要在inputStream的
读操作之前。这些顺序实际上是由http请求的格式决定的。
http 请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content,在connect()函数里面,会根据HttpURLConnection对象的配置值生
成http头,因此在调用connect函数之前,就必须把所有的配置准备好。
紧接着http头的是http请求的正文,正文的内容通过outputStream写入,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是在流关闭
后,根据输入的内容生成http正文。
至此,http请求的东西已经准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回
信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入 outputStream
(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生
post请求的OutputStream实际上不是网络流,而是写入内存,在getInputStream中才真正把写道流里面的内容作为正文与根据之前的配置生成的http request头合并成真正的http request,
并在此时才真正向服务器发送。
HttpURLConnection.setChunkedStreamingMode 函数可以改变这个模式,设置了ChunkedStreamingMode后,不再等待OutputStream关闭后生成完整的http request一次过发送,而是先发送
http request头,正文内容则是网路流的方式实时传送到服务器。实际上是不告诉服务器http正文的长度,这种模式适用于向服务器传送较大的或者是不容易获取长度的数据,如文件。
上一篇: MINA之心跳协议运用
下一篇: MINA之心跳协议运用
推荐阅读
-
C#基于socket模拟http请求的方法
-
Linux下模拟http的get/post请求(curl or wget)详解
-
使用PHP Socket 编程模拟Http post和get请求
-
Node.js模拟发起http请求从异步转同步的5种用法
-
php模拟asp中的XmlHttpRequest实现http请求的代码
-
Python实现模拟浏览器请求及会话保持操作示例
-
如何禁止chrome浏览器http自动转成https 【转】
-
模拟HTTP请求实现网页自动操作及数据采集的方法
-
【笔记】java http请求 HttpURLConnection 302 重定向
-
浏览器输入url到发起http请求所经历的过程