java的URL类使用和模拟POST请求服务器

理解了HTTP的协议的基本请求构造后,我们来讲讲JAVA 的URL类的使用:

URL类是java中常用的网络类,这个类提供了很多的关于请求网络数据的方法:

其实最关键的是

url.openConnection();
URL url=new URL(path);
表示请求对应URL和获得有关的连接。

一般的用法是使用

HttpURLConnection count_length_con=(HttpURLConnection)url.openConnection();
这样来使用:

我们现在细细的表述下这个过程:

回想学过的HTTP的协议的请求过程:

URL url=new URL(path);
这个类的构造方法:其实就是建立三次握手,其实仅仅是建立了一个TCP连接,

HttpURLConnection count_length_con=(HttpURLConnection)url.openConnection();
而这个行代码,才是建立HTTP请求的时刻!

之后,我们可以对HttpUrlconceiton类进行参数设置:

比如:

                                    count_length_con.setDoInput(true);
<pre name="code" class="java" style="color: rgb(61, 61, 61); font-size: 14px; text-align: justify;">                                     count_length_con.setDoOutput(true);
count_length_con.setRequestMethod("GET"); count_length_con.setReadTimeout(1000*60);

 
 
之后,这是在三次握手之后,这一步就是想服务器发送的TCP请求:
                              count_length_con.connect();                                  
</pre><p>这之后,如果是connection.getInputStream();就是已经把请求数据发送完成,正式开启HTTP连接,得到会响应的报文,</p><p>如果是,connection.getOutputStream(),就是在写请求体的内容,此时,也是正式开启HTTP连接。</p><p>接下来我们说说如何去用java来模拟表单的的封装:</p><p><span style="font-family: Arial; font-size: 14px; line-height: 26px; color: rgb(51, 51, 51);">POST的表单的content-type一般有两种类型:application/x-www-form-urlencoded 和</span><span style="font-family: Arial; font-size: 14px; line-height: 26px; color: rgb(61, 61, 61);">multipart/form-data</span></p><p><span style="font-family:Arial;color:#3d3d3d;"><span style="font-size: 14px; line-height: 26px;">如果是第一种方式:因为没有文件类型的数据的时候,</span></span></p><p><span style="font-family:Arial;color:#3d3d3d;"><span style="font-size: 14px; line-height: 26px;"><span style="color: rgb(61, 61, 61); font-family: Arial; font-size: 14px; line-height: 26px;">则这样构造:</span></span></span><pre name="code" class="html">URL("http://jobsearch.dice.com/jobsearch/jobsearch.cgi");
URLConnection connection = url.openConnection();
OutputStreamWriter ut = newOutputStreamWriter(uc.getOutputStream(), "8859_1");
out.write("username=bob&password="+password+"");
// remember to clean up
out.flush();
out.close();
比如想服务器提交username和password数据的时候,用这种方式做请求参数的封装:

,请求的效果如下所示:

POST /jobsearch/jobsearch.cgi HTTP 1.0
ACCEPT: text/plain
Content-type: application/x-www-form-urlencoded
Content-length: 99
username=bob
password=someword

好,接下来讲下如何混合提交含有文件类型的表单(multipart/form-data)

首先,我们来看看这种类型的表单的请求体是如何构造的:

  1. --${bound}  
  2. Content-Disposition: form-data; name="Filename"  
  3.   
  4. HTTP.pdf  
  5. --${bound}  
  6. Content-Disposition: form-data; name="file000"filename="HTTP协议详解.pdf"  
  7. Content-Type: application/octet-stream  
  8.   
  9. %PDF-1.5  
  10. file content  
  11. %%EOF  
  12.   
  13. --${bound}  
  14. Content-Disposition: form-data; name="Upload"  
  15.   
  16. Submit Query  
  17. --${bound}--  


这个是参照别人的,大家可以看到,
  1. --${bound}  是什么呢?这是边界分隔符号,用他来分隔我们混合的表单实体,比如文件,比如请求的字符串,这个分隔符号为
  2. --加上自定义符号,我们怎么去自定义呢?
  3.   httpurlconnection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundry);
  4.    这样就可以自定义了,现在,我们有怎么去模拟呢?

这里就附上我的代码里面的一个函数:

<span style="color:#3d3d3d;">                          String boundry="******";//HTTP报文的分隔符符号
  		          String twoHyphens="--";
  		          String end="\r\n";//报文中换行符号     
    	      try {
					URL url=new URL(url_path);
					
					HttpURLConnection  httpurlconnection=(HttpURLConnection)url.openConnection();
					
					this.PrepareConnection(httpurlconnection);
					
				httpurlconnection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundry);
				    
					FileInputStream file_sd_inputstream=new FileInputStream(file_image);
					
				    DataOutputStream upload_file_server_stream=new DataOutputStream(httpurlconnection.getOutputStream());
				    
				    String file_path=file_image.getAbsolutePath().trim();
				    
				    upload_file_server_stream.writeBytes(twoHyphens+boundry+end);//有边界符号,开始写实体了
				    
			</span><span style="color:#ff0000;">	    upload_file_server_stream.writeBytes("Content-Disposition: form-data;name=\"up_file\"; filename=\" "
				      +file_path.substring(file_path.lastIndexOf("/")+1)+ "\" "+end);</span>
<span style="color: rgb(61, 61, 61);">                    //定义实体内容了,这个实体是文件,描述实体的POST名字和文件的名字,
				    
				   </span><span style="color:#ff0000;"> upload_file_server_stream.writeBytes(end);</span><span style="color:#3d3d3d;">
				    
				    this.WriteFormEntity(upload_file_server_stream, file_sd_inputstream);//这个函数我之后写在下面的代码里面,
				    
				    file_sd_inputstream.close();
				    
				    </span><span style="color:#ff0000;">upload_file_server_stream.writeBytes(end);</span><span style="color:#3d3d3d;">
				    
				    </span><span style="color:#ff0000;">upload_file_server_stream.writeBytes(twoHyphens+boundry+end);</span>
<span style="color:#ff0000;">//写完一个实体后,发现还有实体可以提交,于是,我们还要再写的话,记得在写一次分隔符号</span><span style="color:#3d3d3d;">
				    
				</span><span style="color:#ff0000;">    upload_file_server_stream.writeBytes("Content-Disposition: form-data;name=\"user_id\" "+end);</span><span style="color:#3d3d3d;">
				    
				 </span><span style="color:#ff0000;">   upload_file_server_stream.writeBytes(end);</span><span style="color:#3d3d3d;">
				    
				    upload_file_server_stream.writeBytes("1");
				    
				    </span><span style="color:#ff0000;">upload_file_server_stream.writeBytes(end);</span><span style="color:#3d3d3d;">
				    
				   </span><span style="color:#ff0000;"> upload_file_server_stream.writeBytes(twoHyphens+boundry+twoHyphens+end);//没有想服务器发送的了,用--*******--表示结束</span><span style="color:#3d3d3d;">
				    
				    upload_file_server_stream.flush();
				    
				    String res=this.getServet_back_info(httpurlconnection);
				    
				    upload_file_server_stream.close();
				    
				    this.sendMSG_to_MainThread(res);
    	          } catch (MalformedURLException e) {
					e.printStackTrace();
				}catch(IOException e){
					e.printStackTrace();
				}</span>

上面那个写文件实体的代码:

 private void WriteFormEntity(OutputStream file_outputstream,InputStream file_sd_inputstream)
    	     {
    	    	    byte []buffer=new byte[8192];
    	    	    int len=-1;
    	    	    try {
						while((len=file_sd_inputstream.read(buffer))!=-1)
						{
							   file_outputstream.write(buffer, 0, len);
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
    	     }

大家看到了吧,就是这样的,简单,好用,只要你按照格式来,就很简单啦,

最后注意几点:1.一定要有服务器输入流,不然服务器怎么给你响应呢?这次请求过程都没有结束的说。

                        2.还有就是,记得对输出流flush,和close,及时释放内存,android的内存很珍贵的啊

                       





你可能感兴趣的:(java,Android开发)