<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    在Android的客戶端編程中(特別是SNS 類型的客戶端),經(jīng)常需要實現(xiàn)注冊功能Activity,要用戶輸入用戶名,密碼,郵箱,照片后注冊。但這時就有一個問題,在HTML中用form表單就 能實現(xiàn)如上的注冊表單,需要的信息會自動封裝為完整的HTTP協(xié)議,但在Android中如何把這些參數(shù)和需要上傳的文件封裝為HTTP協(xié)議呢?

    我們可以先做個試驗,看一下form表單到底封裝了什么樣的信息。

    第一步:編寫一個Servlet,把接收到的HTTP信息保存在一個文件中,代碼如下:

    1.     public void doPost(HttpServletRequest request, HttpServletResponse response)
    2.  
    3.            throws ServletException, IOException {
    4.  
    5.  
    6.  
    7.        //獲取輸入流,是HTTP協(xié)議中的實體內(nèi)容
    8.  
    9.        ServletInputStream  sis=request.getInputStream();
    10.  
    11.      
    12.  
    13.        //緩沖區(qū)
    14.  
    15.        byte buffer[]=new byte[1024];
    16.  
    17.       
    18.  
    19.        FileOutputStream fos=new FileOutputStream("d:\\file.log");
    20.  
    21.       
    22.  
    23.        int len=sis.read(buffer, 0, 1024);
    24.  
    25.       
    26.  
    27.        //把流里的信息循環(huán)讀入到file.log文件中
    28.  
    29.        while( len!=-1 )
    30.  
    31.        {
    32.  
    33.            fos.write(buffer, 0, len);
    34.  
    35.            len=sis.readLine(buffer, 0, 1024);
    36.  
    37.        }
    38.  
    39.       
    40.  
    41.        fos.close();
    42.  
    43.        sis.close();
    44.  
    45.       
    46.  
    47.     }
    48.  
    49.  

    第二步:實現(xiàn)如下一個表單頁面, 詳細的代碼如下:

    1. &lt;form action="servlet/ReceiveFile" method="post" enctype="multipart/form-data"&gt;
    2.  
    3.     第一個參數(shù)&lt;input type="text" name="name1"/&gt; &lt;br/&gt;
    4.  
    5.     第二個參數(shù)&lt;input type="text" name="name2"/&gt; &lt;br/&gt;
    6.  
    7.     第一個上傳的文件&lt;input type="file" name="file1"/&gt; &lt;br/&gt;
    8.  
    9.     第二個上傳的文件&lt;input type="file" name="file2"/&gt; &lt;br/&gt;
    10.  
    11.     &lt;input type="submit" value="提交"&gt;
    12.  
    13. &lt;/form&gt;

    注意了,由于要上傳附件,所以一定要設(shè)置enctype為multipart/form-data,才可以實現(xiàn)附件的上傳。

    第三步:填寫完信息后按“提交”按鈕后,在D盤下查找file.log文件用記事本打開,數(shù)據(jù)如下:

    —————————–7d92221b604bc

    Content-Disposition: form-data; name=”name1″

    hello

    —————————–7d92221b604bc

    Content-Disposition: form-data; name=”name2″

    world

    —————————–7d92221b604bc

    Content-Disposition: form-data; name=”file1″; filename=”C:\2.GIF”

    Content-Type: image/gif

    GIF89a

          €   € €€   €€ € €€€€€覽?                                                                                     3  f       3  33 3f 3 3 3 f  f3 ff f f f   ? 檉 櫃 櫶 ?   ? 蘤 虣 燙 ?   3 f   3  3 33 f3 ? ? 33 33333f33?3?33f 3f33ff3f?f?f3 3?3檉3櫃3櫶3?3 3?3蘤3虣3燙3?3 333f3??f  f 3f ff 檉 蘤 f3 f33f3ff3檉3蘤3ff ff3fffff檉f蘤ff f?f檉f櫃f櫶f?f f?f蘤f虣f燙f?f f3fff檉蘤   3 f 櫃 虣 ? ?3?f?櫃3虣3檉 檉3檉f檉櫃f虣f櫃 櫃3櫃f櫃櫃櫶櫃櫶 櫶3櫶f櫶櫃燙櫶? ?3?f?櫃虣   3 f 櫶 燙 ? ?3?f?櫶3燙3蘤 蘤3蘤f蘤櫶f燙f虣 虣3虣f虣櫶櫶虣燙 燙3燙f燙櫶燙燙? ?3?f?櫶燙   3 f ? ? 3 333f3?3?3f f3fff?f?f ?檉櫃櫶??蘤虣燙? 3f??!?   ,   

      e   ??羵Q鸚M!C囑lH馉脝遠5荑p釩?3R?R愣?MV39V5?談re琷?試   3??qn?薵Q燚c?獖i鄲EW艗赥戟j ;

    —————————–7d92221b604bc

    Content-Disposition: form-data; name=”file2″; filename=”C:\2.txt”

    Content-Type: text/plain

    hello everyone!!!

    —————————–7d92221b604bc–

           從表單源碼可知,表單上傳的數(shù)據(jù)有4個:參數(shù)name1和name2,文件file1和file2

    首先從file.log觀察兩個參數(shù)name1和name2的情況。這時候使用UltraEdit打開file.log(因為有些字符在記事本里顯示不出來,所以要用16進制編輯器)

           結(jié)合16進制數(shù)據(jù)和記事本顯示的數(shù)據(jù)可知上傳參數(shù)部分的格式規(guī)律:

    1.       第一行是“—————————–7d92221b604bc”作為分隔符,然后是“\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    2.       第二行

    (1)       首先是HTTP中的擴展頭部分“Content-Disposition: form-data;”,表示上傳的是表單數(shù)據(jù)。

    (2)       “name=”name1″”參數(shù)的名稱。

    (3)       “\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    3.       第三行:“\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    4.       第四行:參數(shù)的值,最后是“\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    由觀察可得,表單上傳的每個參數(shù)都是按照以上1—4的格式構(gòu)造HTTP協(xié)議中的參數(shù)部分。

    結(jié)合16進制數(shù)據(jù)和記事本顯示的數(shù)據(jù)可知上傳文件部分的格式規(guī)律:

    1.       第一行是“—————————–7d92221b604bc”作為分隔符,然后是“\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    2.       第二行:

    a)         首先是HTTP中的擴展頭部分“Content-Disposition: form-data;”,表示上傳的是表單數(shù)據(jù)。

    b)        “name=”file2″;”參數(shù)的名稱。

    c)        “filename=”C:\2.txt””參數(shù)的值。

    d)        “\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    3.       第三行:HTTP中的實體頭部分“Content-Type: text/plain”:表示所接收到得實體內(nèi)容的文件格式。計算機的應(yīng)用中有多種多種通用的文件格式,人們?yōu)槊糠N通用格式都定義了一個名稱,稱為 MIME,MIME的英文全稱是”Multipurpose Internet Mail Extensions” (多功能Internet 郵件擴充服務(wù))

    4.       第四行:“\r\n”(即16進制編輯器顯示的0D 0A)回車換行符。

    5.       第五行開始:上傳的內(nèi)容的二進制數(shù)。

    6.       最后是結(jié)束標志“—————————–7d92221b604bc–”,注意:這個結(jié)束標志和分隔符的區(qū)別是最后多了“–”部分。

    但現(xiàn)在還有一個問題,就是分隔符“—————————–7d92221b604bc”是怎么確定的呢?是不是一定要“7d92221b604bc”這串數(shù)字?

            我們以前的分析只是觀察了HTTP請求的實體部分,可以借用工具觀察完整的HTTP請求看一看有沒有什么線索?

      在IE下用HttpWatch,在Firefox下用Httpfox這個插件,可以實現(xiàn)網(wǎng)頁數(shù)據(jù)的抓包,從圖4可看出,原來在Content-Type部分指定了分隔符所用的字符串。

     
    根據(jù)以上總結(jié)的注冊表單中的參數(shù)傳遞和文件上傳的規(guī)律,我們可以能寫出Android中實現(xiàn)一個用戶注冊功能(包括個人信息填寫和上傳圖片部分)的工具類,

    首先,要有一個javaBean類FormFile封裝文件的信息:

    1. public class FormFile {
    2.  /* 上傳文件的數(shù)據(jù) */
    3.  private byte[] data;
    4.  /* 文件名稱 */
    5.  private String filname;
    6.  /* 表單字段名稱*/
    7.  private String formname;
    8.  /* 內(nèi)容類型 */
    9.  private String contentType = "application/octet-stream"; //需要查閱相關(guān)的資料
    10.  
    11.  public FormFile(String filname, byte[] data, String formname, String contentType) {
    12.   this.data = data;
    13.   this.filname = filname;
    14.   this.formname = formname;
    15.   if(contentType!=null) this.contentType = contentType;
    16.  }
    17.  
    18.  public byte[] getData() {
    19.   return data;
    20.  }
    21.  
    22.  public void setData(byte[] data) {
    23.   this.data = data;
    24.  }
    25.  
    26.  public String getFilname() {
    27.   return filname;
    28.  }
    29.  
    30.  public void setFilname(String filname) {
    31.   this.filname = filname;
    32.  }
    33.  
    34.  public String getFormname() {
    35.   return formname;
    36.  }
    37.  
    38.  public void setFormname(String formname) {
    39.   this.formname = formname;
    40.  }
    41.  
    42.  public String getContentType() {
    43.   return contentType;
    44.  }
    45.  
    46.  public void setContentType(String contentType) {
    47.   this.contentType = contentType;
    48.  }
    49.  
    50. }
    51.  

     
    實現(xiàn)文件上傳的代碼如下:

    /** 
     * 直接通過HTTP協(xié)議提交數(shù)據(jù)到服務(wù)器,實現(xiàn)表單提交功能 
     * @param actionUrl 上傳路徑 
     * @param params 請求參數(shù) key為參數(shù)名,value為參數(shù)值 
     * @param file 上傳文件 
     */ 
    public static String post(String actionUrl, Map<String, String> params, FormFile[] files) {  
        try {             
            String BOUNDARY = “———7d4a6d158c9″; //數(shù)據(jù)分隔線  
            String MULTIPART_FORM_DATA = “multipart/form-data”;  
              
            URL url = new URL(actionUrl);  
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
            conn.setDoInput(true);//允許輸入  
            conn.setDoOutput(true);//允許輸出  
            conn.setUseCaches(false);//不使用Cache  
            conn.setRequestMethod(”POST”);            
            conn.setRequestProperty(”Connection”, “Keep-Alive”);  
            conn.setRequestProperty(”Charset”, “UTF-8″);  
            conn.setRequestProperty(”Content-Type”, MULTIPART_FORM_DATA + “; boundary=” + BOUNDARY);  
     
            StringBuilder sb = new StringBuilder();  
              
            //上傳的表單參數(shù)部分,格式請參考文章  
            for (Map.Entry<String, String> entry : params.entrySet()) {//構(gòu)建表單字段內(nèi)容  
                sb.append(”–”);  
                sb.append(BOUNDARY);  
                sb.append(”\r\n”);  
                sb.append(”Content-Disposition: form-data; name=\”"+ entry.getKey() + “\”\r\n\r\n”);  
                sb.append(entry.getValue());  
                sb.append(”\r\n”);  
            }  
            DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());  
            outStream.write(sb.toString().getBytes());//發(fā)送表單字段數(shù)據(jù)  
             
            //上傳的文件部分,格式請參考文章  
            for(FormFile file : files){  
                StringBuilder split = new StringBuilder();  
                split.append(”–”);  
                split.append(BOUNDARY);  
                split.append(”\r\n”);  
                split.append(”Content-Disposition: form-data;name=\”"+ file.getFormname()+”\”;filename=\”"+ file.getFilname() + “\”\r\n”);  
                split.append(”Content-Type: “+ file.getContentType()+”\r\n\r\n”);  
                outStream.write(split.toString().getBytes());  
                outStream.write(file.getData(), 0, file.getData().length);  
                outStream.write(”\r\n”.getBytes());  
            }  
            byte[] end_data = (”–” + BOUNDARY + “–\r\n”).getBytes();//數(shù)據(jù)結(jié)束標志           
            outStream.write(end_data);  
            outStream.flush();  
            int cah = conn.getResponseCode();  
            if (cah != 200) throw new RuntimeException(”請求url失敗”);  
            InputStream is = conn.getInputStream();  
            int ch;  
            StringBuilder b = new StringBuilder();  
            while( (ch = is.read()) != -1 ){  
                b.append((char)ch);  
            }  
            outStream.close();  
            conn.disconnect();  
            return b.toString();  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  

    posted on 2011-06-09 16:26 ivaneeo 閱讀(3326) 評論(0)  編輯  收藏 所屬分類: java魔力
    主站蜘蛛池模板: 中文免费观看视频网站| 毛片a级毛片免费播放下载| 手机永久免费的AV在线电影网| 国产成人亚洲精品91专区高清| 免费无码一区二区| 99精品视频在线观看免费| 无码日韩精品一区二区三区免费 | 日韩免费观看视频| 1区2区3区产品乱码免费| 91福利免费视频| 成人爱做日本视频免费| 亚洲成av人影院| 久久精品国产亚洲av品善| 久久免费视频一区| 女人让男人免费桶爽30分钟| 亚洲无人区午夜福利码高清完整版| 免费大黄网站在线看| 亚洲国产小视频精品久久久三级 | 在线精品亚洲一区二区| 大地影院MV在线观看视频免费| 免费精品国产日韩热久久| 亚洲一区二区精品视频| 亚洲综合色丁香婷婷六月图片| yy一级毛片免费视频| 日韩高清在线高清免费| 亚洲黄色网址大全| 中文字幕在线成人免费看| 国产一区二区三区在线观看免费| 亚洲天天做日日做天天欢毛片| 人成免费在线视频| 日韩视频在线免费| 亚洲一卡2卡4卡5卡6卡在线99| 在线播放免费人成毛片乱码| 免费人成年激情视频在线观看 | 黄色成人网站免费无码av| 亚洲国产人成在线观看69网站| 在线涩涩免费观看国产精品| 亚洲欧洲一区二区三区| 亚洲国产成人AV网站| 在线观看免费亚洲| 青青青视频免费观看|