• Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件(二)


    Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件第二版

    上次粗略的写了相同功能的代码,这次整理修复了之前的一些BUG,结构也大量修改过了,现在应用更加方便点

    http://blog.csdn.net/zhouzme/article/details/18940279


    直接上代码了:

    ZHttpRequset.java

    package com.ai9475.util;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.methods.HttpRequestBase;
    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.params.BasicHttpParams;
    import org.apache.http.params.HttpConnectionParams;
    import org.apache.http.params.HttpParams;
    import org.apache.http.protocol.HTTP;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.charset.Charset;
    
    /**
     * Created by ZHOUZ on 14-2-3.
     */
    public class ZHttpRequest
    {
        public final String HTTP_GET = "GET";
    
        public final String HTTP_POST = "POST";
    
        /**
         * 当前请求的 URL
         */
        protected String url = "";
    
        /**
         * HTTP 请求的类型
         */
        protected String requsetType = HTTP_GET;
    
        /**
         * 连接请求的超时时间
         */
        protected int connectionTimeout = 5000;
    
        /**
         * 读取远程数据的超时时间
         */
        protected int soTimeout = 10000;
    
        /**
         * 服务端返回的状态码
         */
        protected int statusCode = -1;
    
        /**
         * 当前链接的字符编码
         */
        protected String charset = HTTP.UTF_8;
    
        /**
         * HTTP GET 请求管理器
         */
        protected HttpRequestBase httpRequest= null;
    
        /**
         * HTTP 请求的配置参数
         */
        protected HttpParams httpParameters= null;
    
        /**
         * HTTP 请求响应
         */
        protected HttpResponse httpResponse= null;
    
        /**
         * HTTP 客户端连接管理器
         */
        protected HttpClient httpClient= null;
    
        /**
         * HTTP POST 方式发送多段数据管理器
         */
        protected MultipartEntityBuilder multipartEntityBuilder= null;
    
        /**
         * 绑定 HTTP 请求的事件监听器
         */
        protected OnHttpRequestListener onHttpRequestListener = null;
    
        public ZHttpRequest(){}
    
        public ZHttpRequest(OnHttpRequestListener listener) {
            this.setOnHttpRequestListener(listener);
        }
    
        /**
         * 设置当前请求的链接
         *
         * @param url
         * @return
         */
        public ZHttpRequest setUrl(String url)
        {
            this.url = url;
            return this;
        }
    
        /**
         * 设置连接超时时间
         *
         * @param timeout 单位(毫秒),默认 5000
         * @return
         */
        public ZHttpRequest setConnectionTimeout(int timeout)
        {
            this.connectionTimeout = timeout;
            return this;
        }
    
        /**
         * 设置 socket 读取超时时间
         *
         * @param timeout 单位(毫秒),默认 10000
         * @return
         */
        public ZHttpRequest setSoTimeout(int timeout)
        {
            this.soTimeout = timeout;
            return this;
        }
    
        /**
         * 设置获取内容的编码格式
         *
         * @param charset 默认为 UTF-8
         * @return
         */
        public ZHttpRequest setCharset(String charset)
        {
            this.charset = charset;
            return this;
        }
    
        /**
         * 获取当前 HTTP 请求的类型
         *
         * @return
         */
        public String getRequestType()
        {
            return this.requsetType;
        }
    
        /**
         * 判断当前是否 HTTP GET 请求
         *
         * @return
         */
        public boolean isGet()
        {
            return this.requsetType == HTTP_GET;
        }
    
        /**
         * 判断当前是否 HTTP POST 请求
         *
         * @return
         */
        public boolean isPost()
        {
            return this.requsetType == HTTP_POST;
        }
    
        /**
         * 获取 HTTP 请求响应信息
         *
         * @return
         */
        public HttpResponse getHttpResponse()
        {
            return this.httpResponse;
        }
    
        /**
         * 获取 HTTP 客户端连接管理器
         *
         * @return
         */
        public HttpClient getHttpClient()
        {
            return this.httpClient;
        }
    
        /**
         * 添加一条 HTTP 请求的 header 信息
         *
         * @param name
         * @param value
         * @return
         */
        public ZHttpRequest addHeader(String name, String value)
        {
            this.httpRequest.addHeader(name, value);
            return this;
        }
    
        /**
         * 获取 HTTP GET 控制器
         *
         * @return
         */
        public HttpGet getHttpGet()
        {
            return (HttpGet) this.httpRequest;
        }
    
        /**
         * 获取 HTTP POST 控制器
         *
         * @return
         */
        public HttpPost getHttpPost()
        {
            return (HttpPost) this.httpRequest;
        }
    
        /**
         * 获取请求的状态码
         *
         * @return
         */
        public int getStatusCode()
        {
            return this.statusCode;
        }
    
        /**
         * 通过 GET 方式请求数据
         *
         * @param url
         * @return
         * @throws IOException
         */
        public String get(String url) throws Exception
        {
            this.requsetType = HTTP_GET;
            // 设置当前请求的链接
            this.setUrl(url);
            // 新建 HTTP GET 请求
            this.httpRequest = new HttpGet(this.url);
            // 执行客户端请求
            this.httpClientExecute();
            // 监听服务端响应事件并返回服务端内容
            return this.checkStatus();
        }
    
        /**
         * 获取 HTTP POST 多段数据提交管理器
         *
         * @return
         */
        public MultipartEntityBuilder getMultipartEntityBuilder()
        {
            if (this.multipartEntityBuilder == null) {
                this.multipartEntityBuilder = MultipartEntityBuilder.create();
                // 设置为浏览器兼容模式
                multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
                // 设置请求的编码格式
                multipartEntityBuilder.setCharset(Charset.forName(this.charset));
            }
            return this.multipartEntityBuilder;
        }
    
        /**
         * 配置完要 POST 提交的数据后, 执行该方法生成数据实体等待发送
         */
        public void buildPostEntity()
        {
            // 生成 HTTP POST 实体
            HttpEntity httpEntity = this.multipartEntityBuilder.build();
            this.getHttpPost().setEntity(httpEntity);
        }
    
        /**
         * 发送 POST 请求
         *
         * @param url
         * @return
         * @throws Exception
         */
        public String post(String url) throws Exception
        {
            this.requsetType = HTTP_POST;
            // 设置当前请求的链接
            this.setUrl(url);
            // 新建 HTTP POST 请求
            this.httpRequest = new HttpPost(this.url);
            // 执行客户端请求
            this.httpClientExecute();
            // 监听服务端响应事件并返回服务端内容
            return this.checkStatus();
        }
    
        /**
         * 执行 HTTP 请求
         *
         * @throws Exception
         */
        protected void httpClientExecute() throws Exception
        {
            // 配置 HTTP 请求参数
            this.httpParameters = new BasicHttpParams();
            this.httpParameters.setParameter("charset", this.charset);
            // 设置 连接请求超时时间
            HttpConnectionParams.setConnectionTimeout(this.httpParameters, this.connectionTimeout);
            // 设置 socket 读取超时时间
            HttpConnectionParams.setSoTimeout(this.httpParameters, this.soTimeout);
            // 开启一个客户端 HTTP 请求
            this.httpClient = new DefaultHttpClient(this.httpParameters);
            // 启动 HTTP POST 请求执行前的事件监听回调操作(如: 自定义提交的数据字段或上传的文件等)
            this.getOnHttpRequestListener().onRequest(this);
            // 发送 HTTP 请求并获取服务端响应状态
            this.httpResponse = this.httpClient.execute(this.httpRequest);
            // 获取请求返回的状态码
            this.statusCode = this.httpResponse.getStatusLine().getStatusCode();
        }
    
        /**
         * 读取服务端返回的输入流并转换成字符串返回
         *
         * @throws Exception
         */
        public String getInputStream() throws Exception
        {
            // 接收远程输入流
            InputStream inStream = this.httpResponse.getEntity().getContent();
            // 分段读取输入流数据
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buf)) != -1) {
                baos.write(buf, 0, len);
            }
            // 数据接收完毕退出
            inStream.close();
            // 将数据转换为字符串保存
            return new String(baos.toByteArray(), this.charset);
        }
    
        /**
         * 关闭连接管理器释放资源
         */
        protected void shutdownHttpClient()
        {
            if (this.httpClient != null && this.httpClient.getConnectionManager() != null) {
                this.httpClient.getConnectionManager().shutdown();
            }
        }
    
        /**
         * 监听服务端响应事件并返回服务端内容
         *
         * @return
         * @throws Exception
         */
        protected String checkStatus() throws Exception
        {
            OnHttpRequestListener listener = this.getOnHttpRequestListener();
            String content;
            if (this.statusCode == HttpStatus.SC_OK) {
                // 请求成功, 回调监听事件
                content = listener.onSucceed(this.statusCode, this);
            } else {
                // 请求失败或其他, 回调监听事件
                content = listener.onFailed(this.statusCode, this);
            }
            // 关闭连接管理器释放资源
            this.shutdownHttpClient();
            return content;
        }
    
        /**
         * HTTP 请求操作时的事件监听接口
         */
        public interface OnHttpRequestListener
        {
            /**
             * 初始化 HTTP GET 或 POST 请求之前的 header 信息配置 或 其他数据配置等操作
             *
             * @param request
             * @throws Exception
             */
            public void onRequest(ZHttpRequest request) throws Exception;
    
            /**
             * 当 HTTP 请求响应成功时的回调方法
             *
             * @param statusCode 当前状态码
             * @param request
             * @return 返回请求获得的字符串内容
             * @throws Exception
             */
            public String onSucceed(int statusCode, ZHttpRequest request) throws Exception;
    
            /**
             * 当 HTTP 请求响应失败时的回调方法
             *
             * @param statusCode 当前状态码
             * @param request
             * @return 返回请求失败的提示内容
             * @throws Exception
             */
            public String onFailed(int statusCode, ZHttpRequest request) throws Exception;
        }
    
        /**
         * 绑定 HTTP 请求的监听事件
         *
         * @param listener
         * @return
         */
        public ZHttpRequest setOnHttpRequestListener(OnHttpRequestListener listener)
        {
            this.onHttpRequestListener = listener;
            return this;
        }
    
        /**
         * 获取已绑定过的 HTTP 请求监听事件
         *
         * @return
         */
        public OnHttpRequestListener getOnHttpRequestListener()
        {
            return this.onHttpRequestListener;
        }
    }
    

    在 Activity 中的使用方法(这里我还是只写主体部分代码):

    MainActivity.java

        public void doClick(View view)
        {
            ZHttpRequest get = new ZHttpRequest();
            get
                    .setCharset(HTTP.UTF_8)
                    .setConnectionTimeout(5000)
                    .setSoTimeout(5000);
            get.setOnHttpRequestListener(new ZHttpRequest.OnHttpRequestListener() {
                @Override
                public void onRequest(ZHttpRequest request) throws Exception {
    
                }
    
                @Override
                public String onSucceed(int statusCode, ZHttpRequest request) throws Exception {
                    return request.getInputStream();
                }
    
                @Override
                public String onFailed(int statusCode, ZHttpRequest request) throws Exception {
                    return "GET 请求失败:statusCode "+ statusCode;
                }
            });
    
            ZHttpRequest post = new ZHttpRequest();
            post
                    .setCharset(HTTP.UTF_8)
                    .setConnectionTimeout(5000)
                    .setSoTimeout(10000);
            post.setOnHttpRequestListener(new ZHttpRequest.OnHttpRequestListener() {
                private String CHARSET = HTTP.UTF_8;
                private ContentType TEXT_PLAIN = ContentType.create("text/plain", Charset.forName(CHARSET));
    
                @Override
                public void onRequest(ZHttpRequest request) throws Exception {
                    // 设置发送请求的 header 信息
                    request.addHeader("cookie", "abc=123;456=爱就是幸福;");
                    // 配置要 POST 的数据
                    MultipartEntityBuilder builder = request.getMultipartEntityBuilder();
                    builder.addTextBody("p1", "abc");
                    builder.addTextBody("p2", "中文", TEXT_PLAIN);
                    builder.addTextBody("p3", "abc中文cba", TEXT_PLAIN);
                    if (picPath != null && ! "".equals(picPath)) {
                        builder.addTextBody("pic", picPath);
                        builder.addBinaryBody("file", new File(picPath));
                    }
                    request.buildPostEntity();
                }
    
                @Override
                public String onSucceed(int statusCode, ZHttpRequest request) throws Exception {
                    return request.getInputStream();
                }
    
                @Override
                public String onFailed(int statusCode, ZHttpRequest request) throws Exception {
                    return "POST 请求失败:statusCode "+ statusCode;
                }
            });
    
            TextView textView = (TextView) findViewById(R.id.showContent);
            String content = "初始内容";
            try {
                if (view.getId() == R.id.doGet) {
                    content = get.get("http://www.baidu.com");
                    content = "GET数据:isGet: " + (get.isGet() ? "yes" : "no") + " =>" + content;
                } else {
                    content = post.post("http://192.168.1.6/test.php");
                    content = "POST数据:isPost" + (post.isPost() ? "yes" : "no") + " =>" + content;
                }
    
            } catch (IOException e) {
                content = "IO异常:" + e.getMessage();
            } catch (Exception e) {
                content = "异常:" + e.getMessage();
            }
            textView.setText(content);
        }

    其中 picPath 为 SD 卡中的图片路径 String 类型,我是直接拍照后进行上传用的

    关于拍照显示并上传的代码部分:http://blog.csdn.net/zhouzme/article/details/18952201


    布局页面

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        >
        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical"
                >
                <Button
                    android:id="@+id/doGet"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:layout_marginBottom="10dp"
                    android:text="GET请求"
                    android:onClick="doClick"
                    />
                <Button
                    android:id="@+id/doPost"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:layout_marginBottom="10dp"
                    android:text="POST请求"
                    android:onClick="doClick"
                    />
                <Button
                    android:id="@+id/doPhoto"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:layout_marginBottom="10dp"
                    android:text="拍照"
                    android:onClick="doPhoto"
                    />
                <TextView
                    android:id="@+id/showContent"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="10dp"
                    />
                <ImageView
                    android:id="@+id/showPhoto"
                    android:layout_width="fill_parent"
                    android:layout_height="250dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/add"
                    android:layout_marginBottom="10dp"
                    />
            </LinearLayout>
        </ScrollView>
    </LinearLayout>

    至于服务端我用的 PHP ,只是简单的输出获取到的数据而已

    <?php
    echo 'GET:<br>'. "
    ";
    //print_r(array_map('urldecode', $_GET));
    print_r($_GET);
    echo '<br>'. "
    ". 'POST:<br>'. "
    ";
    //print_r(array_map('urldecode', $_POST));
    print_r($_POST);
    echo '<br>'. "
    ". 'FILES:<br>'. "
    ";
    print_r($_FILES);
    echo '<br>'. "
    ". 'COOKIES:<br>'. "
    ";
    print_r($_COOKIE);



  • 相关阅读:
    使用 Eclipse 调试 Java 程序的 10 个技巧
    oracle9i,10g再谈优化模式参数问题.
    oracle 索引
    解决IE不能在新窗口中向父窗口的下拉框添加项的问题
    获取文档的尺寸:利用Math.max的另一种方式
    揭开constructor属性的神秘面纱
    测试杂感:Windows8也许需要Account Hub
    探索式测试:探索是为了学习
    一次有教益的程序崩溃调试 (下)
    软件测试读书列表 (2013.8)
  • 原文地址:https://www.cnblogs.com/zhouzme/p/5758511.html
Copyright © 2020-2023  润新知