1. 程式人生 > >Android HTTP multipart/form-data 請求協議資訊實現圖片上傳

Android HTTP multipart/form-data 請求協議資訊實現圖片上傳

問題:
Android應用中,當遇到填寫使用者資訊、發表評論等操作,不可避免會遇到“form表單操作”(類似web form操作)上傳圖片的功能。
在這種情況下,使用Android的HTTPConnection/ ApacheHTTP 通過POST 和GET的方式就實現不了。
解決方法:

Android客戶端通過模擬 HTTP multipart/form-data 請求協議資訊實現圖片上傳。

<span style="font-family:KaiTi_GB2312;font-size:14px;">/**  
 * 檔名稱:UploadImage.java  
 *  
 * 版權資訊:Apache License, Version 2.0  
 *  
 * 功能描述:實現圖片檔案上傳。  
 *  
 * 建立日期:2011-5-10  
 *  
 * 作者:Bert Lee  
 */   
   
/*  
 * 修改歷史:  
 */   
public class UploadImage {   
    String multipart_form_data = "multipart/form-data";   
    String twoHyphens = "--";   
    String boundary = "****************fD4fH3gL0hK7aI6";    // 資料分隔符    
    String lineEnd = System.getProperty("line.separator");    // The value is "\r\n" in Windows.    
       
    /*  
     * 上傳圖片內容,格式請參考HTTP 協議格式。  
     * 人人網Photos.upload中的”程式呼叫“http://wiki.dev.renren.com/wiki/Photos.upload#.E7.A8.8B.E5.BA.8F.E8.B0.83.E7.94.A8  
     * 對其格式解釋的非常清晰。  
     * 格式如下所示:  
     * --****************fD4fH3hK7aI6  
     * Content-Disposition: form-data; name="file"; filename="test.jpg"  
     * Content-Type: image/jpeg  
     *  
     * 這兒是檔案的內容,二進位制流的形式  
     */   
    private static void addImageContent(ImageFile file, DataOutputStream output) {
        StringBuilder split = new StringBuilder();
        split.append(twoHyphens + boundary + lineEnd);
        split.append("Content-Disposition: form-data; name=\"" + file.getName() + "\"; filename=\"" + file.getFileName() + "\"" + lineEnd);
        split.append("Content-Type: " + file.getContentType() + lineEnd);
        split.append(lineEnd);
        try {
            output.writeBytes(split.toString());
            output.write(file.getData(), 0, file.getData().length);
            output.writeBytes(lineEnd);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }   
       
    /*  
     * 構建表單欄位內容,格式請參考HTTP 協議格式(用FireBug可以抓取到相關資料)。(以便上傳表單相對應的引數值)  
     * 格式如下所示:  
     * --****************fD4fH3hK7aI6  
     * Content-Disposition: form-data; name="action"  
     * // 一空行,必須有  
     * upload  
     */   
    private static void addFormField(String params, DataOutputStream output) {
        StringBuilder sb = new StringBuilder();
        sb.append(twoHyphens + boundary + lineEnd);
        sb.append("Content-Disposition: form-data; name=\"data\"" + lineEnd);
        sb.append("Content-Type: application/json; charset=utf-8" + lineEnd);
        sb.append(lineEnd);
        sb.append(params + lineEnd);
        try {
            output.writeBytes(sb.toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }   
       
    /**  
     * 直接通過 HTTP 協議提交資料到伺服器,實現表單提交功能。  
     * @param actionUrl 上傳路徑  
     * @param params 請求引數key為引數名,value為引數值  
     * @param files 上傳檔案資訊  
     * @return 返回請求結果  
     */   
    public String post(String actionUrl, Set<Map.Entry<Object,Object>> params, Image[] files) {   
        HttpURLConnection conn = null;   
        DataOutputStream output = null;   
        BufferedReader input = null;   
        try {   
            URL url = new URL(actionUrl);   
            conn = (HttpURLConnection) url.openConnection();   
            conn.setConnectTimeout(120000);   
            conn.setDoInput(true);        // 允許輸入    
            conn.setDoOutput(true);        // 允許輸出    
            conn.setUseCaches(false);    // 不使用Cache    
            conn.setRequestMethod("POST");   
            conn.setRequestProperty("Connection", "keep-alive");   
            conn.setRequestProperty("Content-Type", multipart_form_data + "; boundary=" + boundary);   
               
            conn.connect();   
            output = new DataOutputStream(conn.getOutputStream());   
               
            addImageContent(files, output);    // 新增圖片內容    
               
            addFormField(params, output);    // 新增表單欄位內容    
               
            output.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);// 資料結束標誌    
            output.flush();   
               
            int code = conn.getResponseCode();   
            if(code != 200) {   
                throw new RuntimeException("請求‘" + actionUrl +"’失敗!");   
            }   
               
            input = new BufferedReader(new InputStreamReader(conn.getInputStream()));   
            StringBuilder response = new StringBuilder();   
            String oneLine;   
            while((oneLine = input.readLine()) != null) {   
                response.append(oneLine + lineEnd);   
            }   
               
            return response.toString();   
        } catch (IOException e) {   
            throw new RuntimeException(e);   
        } finally {   
            // 統一釋放資源    
            try {   
                if(output != null) {   
                    output.close();   
                }   
                if(input != null) {   
                    input.close();   
                }   
            } catch (IOException e) {   
                throw new RuntimeException(e);   
            }   
               
            if(conn != null) {   
                conn.disconnect();   
            }   
        }   
    }   
       
    public static void main(String[] args) {   
        try {   
            String response = "";   
               
            BufferedReader in = new BufferedReader(new FileReader("config/actionUrl.properties"));   
            String actionUrl = in.readLine();   
               
            // 讀取表單對應的欄位名稱及其值    
            Properties formDataParams = new Properties();   
            formDataParams.load(new FileInputStream(new File("config/formDataParams.properties")));   
            Set<Map.Entry<Object,Object>> params = formDataParams.entrySet();   
               
            // 讀取圖片所對應的表單欄位名稱及圖片路徑    
            Properties imageParams = new Properties();   
            imageParams.load(new FileInputStream(new File("config/imageParams.properties")));   
            Set<Map.Entry<Object,Object>> images = imageParams.entrySet();   
            Image[] files = new Image[images.size()];   
            int i = 0;   
            for(Map.Entry<Object,Object> image : images) {   
                Image file = new Image(image.getValue().toString(), image.getKey().toString());   
                files[i++] = file;   
            }   
//            Image file = new Image("images/apple.jpg", "upload_file");    
//            Image[] files = new Image[0];    
//            files[0] = file;    
               
            response = new UploadImage().post(actionUrl, params, files);   
            System.out.println("返回結果:" + response);   
        } catch (IOException e) {   
            e.printStackTrace();   
        }   
    }   
}</span> 

原文:http://www.cnblogs.com/top5/archive/2012/03/20/2408014.html

擴充套件:http://blog.csdn.net/u014657752/article/details/48396481