Android模拟 HTTP multipart/form-data 请求协议信息实现图片上传

来源:互联网 发布:linux 向组里添加用户 编辑:程序博客网 时间:2024/05/22 14:10

Android应用中,当遇到填写用户信息、发表评论等操作,不可避免会遇到“form表单操作”(类似web form操作)上传图片的功能。
 
在这种情况下,使用Android的HTTPConnection/ ApacheHTTP 通过POST 和GET的方式就实现不了。
 
解决方法:
 
Android客户端通过模拟 HTTP multipart/form-data 请求协议信息实现图片上传。
 1./**
 2. * 文件名称:UploadImage.java
 3. *
 4. * 版权信息:Apache License, Version 2.0
 5. *
 6. * 功能描述:实现图片文件上传。
 7. *
 8. * 创建日期:2011-5-10
 9. *
 10. * 作者:Bert Lee
 11. */ 
 12. 
 13./*
1.
 2. * 修改历史:
 3. */ 
 4.public class UploadImage { 
 5.    String multipart_form_data = "multipart/form-data"; 
 6.    String twoHyphens = "--"; 
 7.    String boundary = "****************fD4fH3gL0hK7aI6";    // 数据分隔符  
 8.    String lineEnd = System.getProperty("line.separator");    // The value is "\r\n" in Windows.  
 9.     
 10.    /*
 11.     * 上传图片内容,格式请参考HTTP 协议格式。
 12.     * 人人网Photos.upload中的”程序调用“http://wiki.dev.renren.com/wiki/Photos.upload#.E7.A8.8B.E5.BA.8F.E8.B0.83.E7.94.A8
 13.     * 对其格式解释的非常清晰。
 14.     * 格式如下所示:
 15.     * --****************fD4fH3hK7aI6
 16.     * Content-Disposition: form-data; name="upload_file"; filename="apple.jpg"
 17.     * Content-Type: image/jpeg
 18.     *
 19.     * 这儿是文件的内容,二进制流的形式
 20.     */ 
 21.    private void addImageContent(Image[] files, DataOutputStream output) { 
 22.        for(Image file : files) { 
 23.            StringBuilder split = new StringBuilder(); 
 24.            split.append(twoHyphens + boundary + lineEnd); 
 25.            split.append("Content-Disposition: form-data; name=\"" + file.getFormName() + "\"; filename=\"" + file.getFileName() + "\"" + lineEnd); 
 26.            split.append("Content-Type: " + file.getContentType() + lineEnd); 
 27.            split.append(lineEnd); 
 28.            try { 
 29.                // 发送图片数据  
 30.                output.writeBytes(split.toString()); 
 31.                output.write(file.getData(), 0, file.getData().length); 
 32.                output.writeBytes(lineEnd); 
 33.            } catch (IOException e) { 
 34.                throw new RuntimeException(e); 
 35.            } 
 36.        } 
 37.    } 
 38.     
 39.    /*
 40.     * 构建表单字段内容,格式请参考HTTP 协议格式(用FireBug可以抓取到相关数据)。(以便上传表单相对应的参数值)
 41.     * 格式如下所示:
 42.     * --****************fD4fH3hK7aI6
 43.     * Content-Disposition: form-data; name="action"
 44.     * // 一空行,必须有
 45.     * upload
 46.     */ 
 47.    private void addFormField(Set<Map.Entry<Object,Object>> params, DataOutputStream output) { 
 48.        StringBuilder sb = new StringBuilder(); 
 49.        for(Map.Entry<Object, Object> param : params) { 
 50.            sb.append(twoHyphens + boundary + lineEnd); 
 51.            sb.append("Content-Disposition: form-data; name=\"" + param.getKey() + "\"" + lineEnd); 
 52.            sb.append(lineEnd); 
 53.            sb.append(param.getValue() + lineEnd); 
 54.        } 
 55.        try { 
 56.            output.writeBytes(sb.toString());// 发送表单字段数据  
 57.        } catch (IOException e) { 
 58.            throw new RuntimeException(e); 
 59.        } 
 60.    } 
 61.     
 62.    /**
 63.     * 直接通过 HTTP 协议提交数据到服务器,实现表单提交功能。
 64.     * @param actionUrl 上传路径
 65.     * @param params 请求参数key为参数名,value为参数值
 66.     * @param files 上传文件信息
 67.     * @return 返回请求结果
 68.     */ 
 69.    public String post(String actionUrl, Set<Map.Entry<Object,Object>> params, Image[] files) { 
 70.        HttpURLConnection conn = null; 
 71.        DataOutputStream output = null; 
 72.        BufferedReader input = null; 
 73.        try { 
 74.            URL url = new URL(actionUrl); 
 75.            conn = (HttpURLConnection) url.openConnection(); 
 76.            conn.setConnectTimeout(120000); 
 77.            conn.setDoInput(true);        // 允许输入  
 78.            conn.setDoOutput(true);        // 允许输出  
 79.            conn.setUseCaches(false);    // 不使用Cache  
 80.            conn.setRequestMethod("POST"); 
 81.            conn.setRequestProperty("Connection", "keep-alive"); 
 82.            conn.setRequestProperty("Content-Type", multipart_form_data + "; boundary=" + boundary); 
 83.             
 84.            conn.connect(); 
 85.            output = new DataOutputStream(conn.getOutputStream()); 
 86.             
 87.            addImageContent(files, output);    // 添加图片内容  
 88.             
 89.            addFormField(params, output);    // 添加表单字段内容  
 90.             
 91.            output.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);// 数据结束标志  
 92.            output.flush(); 
 93.             
 94.            int code = conn.getResponseCode(); 
 95.            if(code != 200) { 
 96.                throw new RuntimeException("请求‘" + actionUrl +"’失败!"); 
 97.            } 
 98.             
 99.            input = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
 100.            StringBuilder response = new StringBuilder(); 
 101.            String oneLine; 
 102.            while((oneLine = input.readLine()) != null) { 
 103.                response.append(oneLine + lineEnd); 
 104.            } 
 105.             
 106.            return response.toString(); 
 107.        } catch (IOException e) { 
 108.            throw new RuntimeException(e); 
 109.        } finally { 
 110.            // 统一释放资源  
 111.            try { 
 112.                if(output != null) { 
 113.                    output.close(); 
 114.                } 
 115.                if(input != null) { 
 116.                    input.close(); 
 117.                } 
 118.            } catch (IOException e) { 
 119.                throw new RuntimeException(e); 
 120.            } 
 121.             
 122.            if(conn != null) { 
 123.                conn.disconnect(); 
 124.            } 
 125.        } 
 126.    } 
 127.     
 128.    public static void main(String[] args) { 
 129.        try { 
 130.            String response = ""; 
 131.             
 132.            BufferedReader in = new BufferedReader(new FileReader("config/actionUrl.properties")); 
 133.            String actionUrl = in.readLine(); 
 134.             
 135.            // 读取表单对应的字段名称及其值  
 136.            Properties formDataParams = new Properties(); 
 137.            formDataParams.load(new FileInputStream(new File("config/formDataParams.properties"))); 
 138.            Set<Map.Entry<Object,Object>> params = formDataParams.entrySet(); 
 139.             
 140.            // 读取图片所对应的表单字段名称及图片路径  
 141.            Properties imageParams = new Properties(); 
 142.            imageParams.load(new FileInputStream(new File("config/imageParams.properties"))); 
 143.            Set<Map.Entry<Object,Object>> images = imageParams.entrySet(); 
 144.            Image[] files = new Image[images.size()]; 
 145.            int i = 0; 
 146.            for(Map.Entry<Object,Object> image : images) { 
 147.                Image file = new Image(image.getValue().toString(), image.getKey().toString()); 
 148.                files[i++] = file; 
 149.            } 
 150.//            Image file = new Image("images/apple.jpg", "upload_file");  
 151.//            Image[] files = new Image[0];  
 152.//            files[0] = file;  
 153.             
 154.            response = new UploadImage().post(actionUrl, params, files); 
 155.            System.out.println("返回结果:" + response); 
 156.        } catch (IOException e) { 
 157.            e.printStackTrace(); 
 158.        } 
 159.    } 
 160.} 

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-08/41944.htm

原创粉丝点击