乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      http 協(xié)議上傳文件multipart form

       WindySky 2016-05-24

      原文地址:http://xixinfei./blog/2002017

      含義 ENCTYPE="multipart/form-data" 說明: 
      通過 http 協(xié)議上傳文件 rfc1867協(xié)議概述,jsp 應(yīng)用舉例,客戶端發(fā)送內(nèi)容構(gòu)造 

      1、概述在最初的 http 協(xié)議中,沒有上傳文件方面的功能。 rfc1867 (http://www./rfc/rfc1867.txt) 為 http 協(xié)議添加了這個(gè)功能??蛻舳说臑g覽器,如 Microsoft IE, Mozila, Opera 等,按照此規(guī)范將用戶指定的文件發(fā)送到服務(wù)器。服務(wù)器端的網(wǎng)頁程序,如 php, asp, jsp 等,可以按照此規(guī)范,解析出用戶發(fā)送來的文件。Microsoft IE, Mozila, Opera 已經(jīng)支持此協(xié)議,在網(wǎng)頁中使用一個(gè)特殊的 form 就可以發(fā)送文件。絕大部分 http server ,包括 tomcat ,已經(jīng)支持此協(xié)議,可接受發(fā)送來的文件。各種網(wǎng)頁程序,如 php, asp, jsp 中,對(duì)于上傳文件已經(jīng)做了很好的封裝。 

      2、上傳文件的實(shí)例:用 servelet 實(shí)現(xiàn)(http server 為 tomcat 4.1.24)1. 在一個(gè) html 網(wǎng)頁中,寫一個(gè)如下的form : 

      <form enctype="multipart/form-data" action="http://192.168.29.65/UploadFile" method=post>  
      load multi files :<br>    
      <input name="userfile1" type="file"><br>   
      <input name="userfile2" type="file"><br> 
      <input name="userfile3" type="file"><br>    <input name="userfile4" type="file"><br>   
      text field :<input type="text" name="text" value="text"><br>   
      <input type="submit" value="提交"><input type=reset></form> 



      用戶可以選擇多個(gè)文件,填寫表單其它項(xiàng),點(diǎn)擊“提交”按鈕后就開始上傳給 http://192.168.29.65/upload_file/UploadFile 

      這是一個(gè) servelet 程序注意 enctype="multipart/form-data", method=post, type="file" 。根據(jù) rfc1867, 這三個(gè)屬性是必須的。multipart/form-data 是新增的編碼類型,以提高二進(jìn)制文件的傳輸效率。具體的解釋請(qǐng)參閱 rfc18672. 服務(wù)端 servelet 的編寫現(xiàn)在第三方的 http upload file 工具庫很多。Jarkata 項(xiàng)目本身就提供了fileupload 包http://jakarta./commons/fileupload/ 。 

      文件上傳、表單項(xiàng)處理、效率問題基本上都考慮到了。在 Struts 中就使用了這個(gè)包,不過是用 Struts 的方式另行封裝了一次。這里我們直接使用 fileupload 包。至于Struts 中的用法,請(qǐng)參閱 Struts 相關(guān)文檔。這個(gè)處理文件上傳的 servelet 主要代碼如下: 

      public void doPost( HttpServletRequest request, HttpServletResponse response ) 
      {   
          DiskFileUpload diskFileUpload = new DiskFileUpload();    // 允許文件最大長度 
          diskFileUpload.setSizeMax( 100*1024*1024 );    // 設(shè)置內(nèi)存緩沖大小 
          diskFileUpload.setSizeThreshold( 4096 );    // 設(shè)置臨時(shí)目錄   
          diskFileUpload.setRepositoryPath( "c:/tmp" );  
          List fileItems = diskFileUpload.parseRequest( request );  
          Iterator iter = fileItems.iterator();    for( ; iter.hasNext(); ) 
          {    
          FileItem fileItem = (FileItem) iter.next();   
            if( fileItem.isFormField() ) {         // 當(dāng)前是一個(gè)表單項(xiàng)    
          out.println( "form field : " + fileItem.getFieldName() + ", " + fileItem.getString() );    
            } else {       
          // 當(dāng)前是一個(gè)上傳的文件       
          String fileName = fileItem.getName();  
          fileItem.write( new File("c:/uploads/"+fileName) );     
            }  

      }} 



      為簡略起見,異常處理,文件重命名等細(xì)節(jié)沒有寫出。3、 客戶端發(fā)送內(nèi)容構(gòu)造假設(shè)接受文件的網(wǎng)頁程序位于 http://192.168.29.65/upload_file/UploadFile.假設(shè)我們要發(fā)送一個(gè)二進(jìn)制文件、一個(gè)文本框表單項(xiàng)、一個(gè)密碼 框表單項(xiàng)。文件名為 E:\s ,其內(nèi)容如下:(其中的XXX代表二進(jìn)制數(shù)據(jù),如 01 02 03)abbXXXccc 客戶端應(yīng)該向 192.168.29.65 發(fā)送如下內(nèi)容: 


      POST /upload_file/UploadFile HTTP/1.1 
      Accept: text/plain, */* 
      Accept-Language: zh-cn 
      Host: 192.168.29.65:80 
      Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6 
      User-Agent: Mozilla/4.0 (compatible; OpenOffice.org) 
      Content-Length: 424 
      Connection: Keep-Alive -----------------------------7d33a816d302b6 
      Content-Disposition:form-data; 
      name="userfile1"; 
      filename="E:\s"Content-Type: 
      application/octet-stream abbXXXccc 
      -----------------------------7d33a816d302b6 

      Content-Disposition: form-data; 

      name="text1" foo 

      -----------------------------7d33a816d302b6 

      Content-Disposition: form-data; 

      name="password1" bar 

      -----------------------------7d33a816d302b6-- 


      (上面有一個(gè)回車)此內(nèi)容必須一字不差,包括最后的回車。 

      注意:Content-Length: 424 這里的424是紅色內(nèi)容的總長度(包括最后的回車) 
      注意這一行:Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6 

      根據(jù) rfc1867, multipart/form-data是必須的.---------------------------7d33a816d302b6 是分隔符,分隔多個(gè)文件、表單項(xiàng)。 

      其中33a816d302b6 是即時(shí)生成的一個(gè)數(shù)字,用以確保整個(gè)分隔符不會(huì)在文件或表單項(xiàng)的內(nèi)容中出現(xiàn)。前面的 ---------------------------7d 是 IE 特有的標(biāo)志。 

      Mozila 為---------------------------71用手工發(fā)送這個(gè)例子,在上述的 servlet 中檢驗(yàn)通過。 




      使用POST發(fā)送數(shù)據(jù) 

        以POST方式發(fā)送數(shù)據(jù)主要是為了向服務(wù)器發(fā)送較大量的客戶端的數(shù)據(jù),它不受URL的長度限制。POST請(qǐng)求將數(shù)據(jù)以URL編碼的形式放在 HTTP正文中,字段形式為fieldname=value,用&分隔每個(gè)字段。注意所有的字段都被作為字符串處理。實(shí)際上我們要做的就是模擬瀏 覽器POST一個(gè)表單。以下是IE發(fā)送一個(gè)登陸表單的POST請(qǐng)求: 

      POST http://127.0.0.1/login.do HTTP/1.0 
      Accept: image/gif, image/jpeg, image/pjpeg, */* 
      Accept-Language: en-us,zh-cn;q=0.5 
      Content-Type: application/x-www-form-urlencoded 
      User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) 
      Content-Length: 28 
      \r\n 
      username=admin&password=1234 


        要在MIDP應(yīng)用程序中模擬瀏覽器發(fā)送這個(gè)POST請(qǐng)求,首先設(shè)置HttpConnection的請(qǐng)求方式為POST: 

      hc.setRequestMethod(HttpConnection.POST); 


        然后構(gòu)造出HTTP正文: 

      byte[] data = "username=admin&password=1234".getBytes(); 

        并計(jì)算正文長度,填入Content-Type和Content-Length: 

      hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
      hc.setRequestProperty("Content-Length", String.valueOf(data.length)); 

        然后打開OutputStream將正文寫入: 

      OutputStream output = hc.openOutputStream(); 
      output.write(data); 


        需要注意的是,數(shù)據(jù)仍需要以URL編碼格式編碼,由于MIDP庫中沒有J2SE中與之對(duì)應(yīng)的URLEncoder類,因此,需要自己動(dòng)手編寫 這個(gè)encode()方法,可以參考java.net.URLEncoder.java的源碼。剩下的便是讀取服務(wù)器響應(yīng),代碼與GET一致,這里就不再 詳述。 

        使用multipart/form-data發(fā)送文件 

        如果要在MIDP客戶端向服務(wù)器上傳文件,我們就必須模擬一個(gè)POST multipart/form-data類型的請(qǐng)求,Content-Type必須是multipart/form-data。 

        以multipart/form-data編碼的POST請(qǐng)求格式與application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP請(qǐng)求頭設(shè)置一個(gè)分隔符,例如ABCD: 

      hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD"); 

        然后,將每個(gè)字段用“--分隔符”分隔,最后一個(gè)“--分隔符--”表示結(jié)束。例如,要上傳一個(gè)title字段"Today"和一個(gè)文件C:\1.txt,HTTP正文如下: 

      --ABCD 
      Content-Disposition: form-data; name="title" 
      \r\n 
      Today 
      --ABCD 
      Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt" 
      Content-Type: text/plain 
      \r\n 
      <這里是1.txt文件的內(nèi)容> 
      --ABCD-- 
      \r\n 


        請(qǐng)注意,每一行都必須以\r\n結(jié)束,包括最后一行。如果用Sniffer程序檢測(cè)IE發(fā)送的POST請(qǐng)求,可以發(fā)現(xiàn)IE的分隔符類似于 ---------------------------7d4a6d158c9,這是IE產(chǎn)生的一個(gè)隨機(jī)數(shù),目的是防止上傳文件中出現(xiàn)分隔符導(dǎo)致服務(wù)器 無法正確識(shí)別文件起始位置。我們可以寫一個(gè)固定的分隔符,只要足夠復(fù)雜即可。 

        發(fā)送文件的POST代碼如下: 

      String[] props = ... // 字段名 
      String[] values = ... // 字段值 
      byte[] file = ... // 文件內(nèi)容 
      String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符 
      StringBuffer sb = new StringBuffer(); 
      // 發(fā)送每個(gè)字段: 
      for(int i=0; i 
      sb = sb.append("--"); 
      sb = sb.append(BOUNDARY); 
      sb = sb.append("\r\n"); 
      sb = sb.append("Content-Disposition: form-data; name=\""+ props[i] + "\"\r\n\r\n"); 
      sb = sb.append(URLEncoder.encode(values[i])); 
      sb = sb.append("\r\n"); 

      // 發(fā)送文件: 
      sb = sb.append("--"); 
      sb = sb.append(BOUNDARY); 
      sb = sb.append("\r\n"); 
      sb = sb.append("Content-Disposition: form-data; name=\"1\"; filename=\"1.txt\"\r\n"); 
      sb = sb.append("Content-Type: application/octet-stream\r\n\r\n"); 
      byte[] data = sb.toString().getBytes(); 
      byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); 
      // 設(shè)置HTTP頭: 
      hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY); 
      hc.setRequestProperty("Content-Length", String.valueOf(data.length + file.length + end_data.length)); 
      // 輸出: 
      output = hc.openOutputStream(); 
      output.write(data); 
      output.write(file); 
      output.write(end_data); 
      // 讀取服務(wù)器響應(yīng): 
      // TODO...

      關(guān)于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related

      最近項(xiàng)目中用到的一個(gè)是用一個(gè)頁面接收c程序post過來的一斷字符串..總接收不到值...

      我用C#寫一個(gè)測(cè)試可以正常接收到值.

      最后抓包比較

       

      區(qū)別只是
      Content-Type:application/x-www-form-urlencoded 
      和 
      Content-Type:multipart/related

      查資料得:

       application/x-www-form-urlencoded: 窗體數(shù)據(jù)被編碼為名稱/值對(duì)。這是標(biāo)準(zhǔn)的編碼格式。multipart/form-data: 窗體數(shù)據(jù)被編碼為一條消息,頁上的每個(gè)控件對(duì)應(yīng)消息中的一個(gè)部分。 text/plain: 窗體數(shù)據(jù)以純文本形式進(jìn)行編碼,其中不含任何控件或格式字符。
       補(bǔ)充
      form 的enctype屬性為編碼方式,常用有兩種:application/x-www-form-urlencoded和multipart/form- data,默認(rèn)為application/x-www-form-urlencoded。 當(dāng)action為get時(shí)候,瀏覽器用x-www-form-urlencoded的編碼方式把form數(shù)據(jù)轉(zhuǎn)換成一個(gè)字串(name1=value1& amp;name2=value2...),然后把這個(gè)字串a(chǎn)ppend到url后面,用?分割,加載這個(gè)新的url。 當(dāng)action為post時(shí)候,瀏覽器把form數(shù)據(jù)封裝到http body中,然后發(fā)送到server。 如果沒有type=file的控件,用默認(rèn)的application/x-www-form-urlencoded就可以了。 但是如果有type=file的話,就要用到multipart/form-data了。瀏覽器會(huì)把整個(gè)表單以控件為單位分割,并為每個(gè)部分加上 Content-Disposition(form-data或者file),Content-Type(默認(rèn)為text/plain),name(控件 name)等信息,并加上分割符(boundary)。

      boundary  是客戶端瀏覽器隨機(jī)生成的
      你可以不用提取。
      提交數(shù)據(jù)的時(shí)候設(shè)置一個(gè)串給他
      并用該串來分隔數(shù)據(jù)
      就可以了

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多