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>'. "\n";
//print_r(array_map('urldecode', $_GET));
print_r($_GET);
echo '<br>'. "\n". 'POST:<br>'. "\n";
//print_r(array_map('urldecode', $_POST));
print_r($_POST);
echo '<br>'. "\n". 'FILES:<br>'. "\n";
print_r($_FILES);
echo '<br>'. "\n". 'COOKIES:<br>'. "\n";
print_r($_COOKIE);



目录
相关文章
|
4天前
|
缓存 应用服务中间件 Apache
HTTP 范围Range请求
HTTP范围请求是一种强大的技术,允许客户端请求资源的部分内容,提高了传输效率和用户体验。通过正确配置服务器和实现范围请求,可以在视频流、断点续传下载等场景中发挥重要作用。希望本文提供的详细介绍和示例代码能帮助您更好地理解和应用这一技术。
41 19
|
12天前
|
JSON JavaScript 前端开发
什么是HTTP POST请求?初学者指南与示范
HTTP POST请求是一种常用的HTTP方法,主要用于向服务器发送数据。通过合理设置请求头和请求主体,可以实现数据的可靠传输。无论是在客户端使用JavaScript,还是在服务器端使用Node.js,理解和掌握POST请求的工作原理和应用场景,对于Web开发至关重要。
132 18
|
11天前
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
54 2
|
29天前
|
Web App开发 大数据 应用服务中间件
什么是 HTTP Range请求(范围请求)
HTTP Range 请求是一种非常有用的 HTTP 功能,允许客户端请求资源的特定部分,从而提高传输效率和用户体验。通过合理使用 Range 请求,可以实现断点续传、视频流播放和按需加载等功能。了解并掌握 HTTP Range 请求的工作原理和应用场景,对开发高效的网络应用至关重要。
65 15
|
29天前
|
Web App开发 网络安全 数据安全/隐私保护
Lua中实现HTTP请求的User-Agent自定义
Lua中实现HTTP请求的User-Agent自定义
|
Android开发
我的Android进阶之旅------&gt;Android发送GET和POST以及HttpClient发送POST请求给服务器响应
效果如下图所示:   布局main.xml   string.xml Hello World, MainActivity! 资讯管理 标题 时长 ...
1080 0
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
30天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
53 19
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
30天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
59 14