Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件
折腾了好几天的 HTTP 终于搞定了,经测试正常,不过是初步用例测试用的,因为后面还要修改先把当前版本保存在博客里吧。
其中POST因为涉及多段上传需要导入两个包文件,我用的是最新的 httpmine4.3 发现网上很多 MultipartEntity 相关的文章都是早起版本的,以前的一些方法虽然还可用,但新版本中已经不建议使用了,所以全部使用新的方式 MultipartEntityBuilder 来处理了。
httpmime-4.3..jar
httpcore-4.3..jar
下载地址: http://hc.apache.org/downloads.cgi
有些镜像貌似打不开,页面上可以可以选择国内的 .cn 后缀的域名镜像服务器来下载
如果是 android studio 这里可能会遇到一个问题: Android Duplicate files copied in APK
经测试 POST 对中文处理也是正常的,没有发现乱码
ZHttpRequest.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.ContentType;
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.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; /**
* Created by ZHOUZ on 14-2-3.
*/
public class ZHttpRequest
{
protected String url = ""; protected Map<String, String> headers = null; protected int connectionTimeout = ; protected int soTimeout = ; protected int statusCode = ; protected String charset = HTTP.UTF_8; protected HttpGet httpGet; protected HttpPost httpPost; protected HttpParams httpParameters; protected HttpResponse httpResponse; protected HttpClient httpClient; protected String inputContent; /**
* 设置当前请求的链接
*
* @param url
* @return
*/
public ZHttpRequest setUrl(String url)
{
this.url = url;
return this;
} /**
* 设置请求的 header 信息
*
* @param headers
* @return
*/
public ZHttpRequest setHeaders(Map headers)
{
this.headers = headers;
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 HttpResponse getHttpResponse()
{
return this.httpResponse;
} /**
* 获取 HTTP 客户端连接管理器
*
* @return
*/
public HttpClient getHttpClient()
{
return this.httpClient;
} /**
* 获取请求的状态码
*
* @return
*/
public int getStatusCode()
{
return this.statusCode;
} /**
* 通过 GET 方式请求数据
*
* @param url
* @return
* @throws IOException
*/
public String get(String url) throws IOException
{
// 设置当前请求的链接
this.setUrl(url);
// 实例化 GET 连接
this.httpGet = new HttpGet(this.url);
// 自定义配置 header 信息
this.addHeaders(this.httpGet);
// 初始化客户端请求
this.initHttpClient();
// 发送 HTTP 请求
this.httpResponse = this.httpClient.execute(this.httpGet);
// 读取远程数据
this.getInputStream();
// 远程请求状态码是否正常
if (this.statusCode != HttpStatus.SC_OK) {
return null;
}
// 返回全部读取到的字符串
return this.inputContent;
} public String post(String url, Map<String, String> datas, Map<String, String> files) throws IOException
{
this.setUrl(url);
// 实例化 GET 连接
this.httpPost = new HttpPost(this.url);
// 自定义配置 header 信息
this.addHeaders(this.httpPost);
// 初始化客户端请求
this.initHttpClient();
Iterator iterator = datas.entrySet().iterator();
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.setCharset(Charset.forName(this.charset));
// 发送的数据
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
multipartEntityBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create("text/plain", Charset.forName(this.charset)));
}
// 发送的文件
if (files != null) {
iterator = files.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
String path = entry.getValue();
if ("".equals(path) || path == null) continue;
File file = new File(entry.getValue());
multipartEntityBuilder.addBinaryBody(entry.getKey(), file);
}
}
// 生成 HTTP 实体
HttpEntity httpEntity = multipartEntityBuilder.build();
// 设置 POST 请求的实体部分
this.httpPost.setEntity(httpEntity);
// 发送 HTTP 请求
this.httpResponse = this.httpClient.execute(this.httpPost);
// 读取远程数据
this.getInputStream();
// 远程请求状态码是否正常
if (this.statusCode != HttpStatus.SC_OK) {
return null;
}
// 返回全部读取到的字符串
return this.inputContent.toString();
} /**
* 为 HTTP 请求添加 header 信息
*
* @param request
*/
protected void addHeaders(HttpRequestBase request)
{
if (this.headers != null) {
Set keys = this.headers.entrySet();
Iterator iterator = keys.iterator();
Map.Entry<String, String> entry;
while (iterator.hasNext()) {
entry = (Map.Entry<String, String>) iterator.next();
request.addHeader(entry.getKey().toString(), entry.getValue().toString());
}
}
} /**
* 配置请求参数
*/
protected void setParams()
{
this.httpParameters = new BasicHttpParams();
this.httpParameters.setParameter("charset", this.charset);
// 设置 连接请求超时时间
HttpConnectionParams.setConnectionTimeout(this.httpParameters, this.connectionTimeout);
// 设置 socket 读取超时时间
HttpConnectionParams.setSoTimeout(this.httpParameters, this.soTimeout);
} /**
* 初始化配置客户端请求
*/
protected void initHttpClient()
{
// 配置 HTTP 请求参数
this.setParams();
// 开启一个客户端 HTTP 请求
this.httpClient = new DefaultHttpClient(this.httpParameters);
} /**
* 读取远程数据
*
* @throws IOException
*/
protected void getInputStream() throws IOException
{
// 接收远程输入流
InputStream inStream = this.httpResponse.getEntity().getContent();
// 分段读取输入流数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[];
int len = -;
while ((len = inStream.read(buf)) != -) {
baos.write(buf, , len);
}
// 将数据转换为字符串保存
this.inputContent = new String(baos.toByteArray());
// 数据接收完毕退出
inStream.close();
// 获取请求返回的状态码
this.statusCode = this.httpResponse.getStatusLine().getStatusCode();
} /**
* 关闭连接管理器释放资源
*/
protected void shutdownHttpClient()
{
if (this.httpClient != null && this.httpClient.getConnectionManager() != null) {
this.httpClient.getConnectionManager().shutdown();
}
}
}
MainActivity.java
这个我就只写事件部分了
public void doClick(View view)
{
ZHttpRequest request = new ZHttpRequest();
String url = "";
TextView textView = (TextView) findViewById(R.id.showContent);
String content = "空内容";
try {
if (view.getId() == R.id.doGet) {
url = "http://www.baidu.com";
content = "GET数据:" + request.get(url);
} else {
url = "http://192.168.1.6/test.php";
HashMap<String, String> datas = new HashMap<String, String>();
datas.put("p1", "abc");
datas.put("p2", "中文");
datas.put("p3", "abc中文cba");
datas.put("pic", this.picPath);
HashMap<String, String> files = new HashMap<String, String>();
files.put("file", this.picPath);
content = "POST数据:" + request.post(url, datas, files);
} } catch (IOException e) {
content = "IO异常:" + e.getMessage();
} catch (Exception e) {
content = "异常:" + e.getMessage();
}
textView.setText(content);
}
其中的 this.picPath 就是指定的SD卡中的相片路径 String 类型
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"
/>
<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"
/>
<TextView
android:id="@+id/showContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
由于我现在对Java 还不是很熟悉,只看过一些视频教程,实际开发经验不多,我按自己的理解写的注释,不过应该不会有什么太大问题吧,如有错误请指出,谢谢!
Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件的更多相关文章
- Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件(二)
Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件第二版 上次粗略的写了相同功能的代码,这次整理修复了之前的一些BUG,结构也大量修改 ...
- 【httpclient-4.3.1.jar】httpclient发送get、post请求以及携带数据上传文件
1.发送get.post携带参数以及post请求接受JSON数据: package cn.qlq.utils; import java.io.BufferedReader; import java.i ...
- Java中使用HttpPost上传文件以及HttpGet进行API请求(包含HttpPost上传文件)
Java中使用HttpPost上传文件以及HttpGet进行API请求(包含HttpPost上传文件) 一.HttpPost上传文件 public static String getSuffix(fi ...
- Android 利用an框架快速实现网络请求(含下载上传文件)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/22573081来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. an框架的网络框架是完全 ...
- curl 模拟GET\POST请求,以及curl post上传文件
https://blog.csdn.net/fungleo/article/details/80703365
- python发送post请求上传文件,无法解析上传的文件
前言 近日,在做接口测试时遇到一个奇葩的问题. 使用post请求直接通过接口上传文件,无法识别文件. 遇到的问题 以下是抓包得到的信息: 以上请求是通过Postman直接发送请求的. 在这里可以看到消 ...
- c#代码发送post请求,上传文件(并带其他参数)
本人对post理解不深,前段时间遇到一个需要用c#代码发送post请求上传文件的业务,于是参考了几篇帖子,加上自身实践写出了如下代码.写的比较low 望各位大大指正^_^. 业务需求: 对方给了一个接 ...
- go 发送post请求(键值对、上传文件、上传zip)
一.post请求的Content-Type为键值对 1.PostForm方式 package main import ( "net/http" "net/url" ...
- restTemple发送请求、上传文件(@LoadBalanced微服务调用及url调用)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Co ...
随机推荐
- 使用asp.net上传图片并且裁剪的方法
工欲善其事,必先利其器,坚持才能更好 这篇文章主要是强调怎么使用asp.net上传图片并且能够裁剪,这个功能主要使用在注册信息的时候需要上传头像并且图片格式很大的时候能够把图片裁剪成更小的图片.下面来 ...
- 查看Unix系统是32位还是64位
#getconf查看OS位数 以下经过测试了HP: getconf KERNEL_BITSLinux: getconf LONG_BITAIX: getconf KERNEL_BITMODE #AIX ...
- IOS开发之NSObject协议类方法说明
oc中NSObject类是所有类的基类,所有类都要继承自它,那么它的方法就显得特别重要,因为所有类都会有这些基本的方法. 看看oc的源码中NSObject是这样定义的: @interface NSOb ...
- ios--socket
一.打开服务器 a.在终端打开,到服务器文件路径输入命令 python chatserver.py b.当显示 Iphone Chat server started 表示成功 二.建立连接 a.设置对 ...
- c#重要特性之一委托
委托的构成必须满足的4个条件: 声明委托类型: 必须有一个方法包含了要执行的代码: 必须创建一个委托实例: 必须调用(invoke)委托实例 委托包装的方法需要满足以下条件 方法的签名必须与委托一致, ...
- .net LINQ and PLINQ
本文 学习自 微软官网文档 2016/12 LINQ 背景 以前写与DB 相关的代码, 程序员须要懂开发语言(C#, VB)和查询语言跟数据库交互. LINQ 的出现使应用程序形成基于集合 ...
- [翻译][MVC 5 + EF 6] 6:创建更复杂的数据模型
原文:Creating a More Complex Data Model for an ASP.NET MVC Application 前面的教程中,我们使用的是由三个实体组成的简单的数据模型.在本 ...
- DataTable 数据量大时,导致内存溢出的解决方案
/// <summary> /// 分解数据表 /// </summary> /// <param name="originalTab">需要分 ...
- ASP.NET DataList嵌套实现评论效果
问题: Datalist1显示say这个表的数据 然后想在Datalist1中嵌套一个Datalist2用于显示对应的评论表2的 sayID对应表1的id,若表2中找不到对应sayId则在对应的Dat ...
- MongoDB的timezone问题
MongoDB是以UTC格式来存储所有时间的,查询的时候也是返回UTC时间,不提供在数据库连接级别的timezone支持,这就带来一个问题:无法使用groupby对日期进行聚合,因为你所在的timez ...