理解了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)
首先,我们来看看这种类型的表单的请求体是如何构造的:
这里就附上我的代码里面的一个函数:
<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的内存很珍贵的啊