zoukankan      html  css  js  c++  java
  • Android模拟 HTTP multipart/formdata 请求协议信息实现图片上传

    问题:

    Android应用中,当遇到填写用户信息、发表评论等操作,不可避免会遇到“form表单操作”(类似web form操作)上传图片的功能。

    在这种情况下,使用Android的HTTPConnection/ ApacheHTTP 通过POST 和GET的方式就实现不了。

    解决方法:


    Android客户端通过模拟 HTTP multipart/form-data 请求协议信息实现图片上传。

    /** 
     * 文件名称: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="upload_file"; filename="apple.jpg" 
         * Content-Type: image/jpeg 
         * 
         * 这儿是文件的内容,二进制流的形式 
         */  
        private void addImageContent(Image[] files, DataOutputStream output) {  
            for(Image file : files) {  
                StringBuilder split = new StringBuilder();  
                split.append(twoHyphens + boundary + lineEnd);  
                split.append("Content-Disposition: form-data; name=\"" + file.getFormName() + "\"; 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 (IOException e) {  
                    throw new RuntimeException(e);  
                }  
            }  
        }  
          
        /* 
         * 构建表单字段内容,格式请参考HTTP 协议格式(用FireBug可以抓取到相关数据)。(以便上传表单相对应的参数值) 
         * 格式如下所示: 
         * --****************fD4fH3hK7aI6 
         * Content-Disposition: form-data; name="action" 
         * // 一空行,必须有 
         * upload 
         */  
        private void addFormField(Set<Map.Entry<Object,Object>> params, DataOutputStream output) {  
            StringBuilder sb = new StringBuilder();  
            for(Map.Entry<Object, Object> param : params) {  
                sb.append(twoHyphens + boundary + lineEnd);  
                sb.append("Content-Disposition: form-data; name=\"" + param.getKey() + "\"" + lineEnd);  
                sb.append(lineEnd);  
                sb.append(param.getValue() + lineEnd);  
            }  
            try {  
                output.writeBytes(sb.toString());// 发送表单字段数据   
            } catch (IOException 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();  
            }  
        }  

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

  • 相关阅读:
    11组 团队展示
    11组Alpha冲刺4/6
    11组Alpha冲刺2/6
    11组Alpha冲刺3/6
    EF code first 分页显示
    多条件分页存储过程控制器写法
    UML的9种图
    C#设计模式(2)——简单工厂模式
    多条件分页存储过程PageCommon写法
    五分钟读懂UML类图
  • 原文地址:https://www.cnblogs.com/zhwl/p/2406070.html
Copyright © 2011-2022 走看看