1.android 向服务器Get和Post请求的两种方式,android向服务器发送文件,自己组装协议和借助第三方开源
- /**
- * @author intbird@163.com
- * @time 20140606
- */
- package com.intbird.utils;
- import java.io.BufferedReader;
- import java.io.DataOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLConnection;
- import java.net.URLDecoder;
- import java.net.URLEncoder;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.mime.MultipartEntity;
- import org.apache.http.entity.mime.content.FileBody;
- import org.apache.http.entity.mime.content.StringBody;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.util.EntityUtils;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Handler;
- import android.os.Message;
- public class ConnInternet {
- /**
- * 开始连接
- */
- public static int HTTP_STATUS_START=0;
- /**
- * 连接过程出错
- */
- public static int HTTP_STATUS_ERROR=400;
- /**
- * 请求成功,返回数据
- */
- public static int HTTP_STATUS_REULTOK=200;
- /**
- * 服务器未响应
- */
- public static int HTTP_STATUS_NORESP=500;
- /**
- * 普通GET请求
- * @param api
- * @param callBack
- */
- public static void get1(final String api,final ConnInternetCallback callBack) {
- final Handler handler=getHandle(api, callBack);
- new Thread(){
- @Override
- public void run() {
- Message msg=handler.obtainMessage(HTTP_STATUS_START, "开始连接");
- try {
- URL url = new URL(api);
- HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
- int resCode=urlConn.getResponseCode();
- if(resCode!=HTTP_STATUS_REULTOK){
- msg.what=HTTP_STATUS_NORESP;
- msg.obj=resCode;
- handler.sendMessage(msg);
- return ;
- }
- InputStreamReader inStream=new InputStreamReader(urlConn.getInputStream());
- BufferedReader buffer=new BufferedReader(inStream);
- String result="";
- String inputLine=null;
- while((inputLine=buffer.readLine())!=null){
- result+=inputLine;
- }
- msg.what=HTTP_STATUS_REULTOK;
- msg.obj=URLDecoder.decode(result,"UTF-8");
- inStream.close();
- urlConn.disconnect();
- } catch (Exception ex) {
- msg.what=HTTP_STATUS_ERROR;
- msg.obj=ex.getMessage().toString();
- }
- finally{
- handler.sendMessage(msg);
- }
- }
- }.start();
- }
- public void get3(final String api,final ConnInternetCallback callBack) {
- final Handler handler=getHandle(api, callBack);
- new Thread(){
- @Override
- public void run() {
- Message msg=handler.obtainMessage(HTTP_STATUS_START, "开始连接");
- try {
- HttpGet httpGet=new HttpGet(api);
- HttpClient httpClient = new DefaultHttpClient();
- HttpResponse httpResp = httpClient.execute(httpGet);
- int resCode=httpResp.getStatusLine().getStatusCode();
- if(resCode!=HTTP_STATUS_REULTOK){
- msg.what=HTTP_STATUS_NORESP;
- msg.obj=resCode;
- handler.sendMessage(msg);
- return ;
- }
- msg.what=HTTP_STATUS_REULTOK;
- msg.obj= EntityUtils.toString(httpResp.getEntity());
- }catch (Exception e) {
- msg.what=HTTP_STATUS_ERROR;
- msg.obj= e.getMessage();
- }
- finally{
- handler.sendMessage(msg);
- }
- }
- }.start();
- }
- private static Handler getHandle(final String api,final ConnInternetCallback callBack){
- return new Handler() {
- @Override
- public void handleMessage(Message message) {
- //不 在 这里写!
- callBack.callBack(message.what,api, message.obj.toString());
- }
- };
- }
- /**
- * 简单类型,只进行文字信息的POST;
- * @param api api地址
- * @param params 仅字段参数
- * @param callBack 返回调用;
- */
- public static void post1(final String api,final HashMap<String,String> params,final ConnInternetCallback callBack){
- final Handler handler=getHandle(api, callBack);
- new Thread(){
- @Override
- public void run() {
- Message msg=handler.obtainMessage(HTTP_STATUS_START,"开始连接");
- try {
- URL url=new URL(api);
- HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
- urlConn.setDoInput(true);
- urlConn.setDoOutput(true);
- urlConn.setRequestMethod("POST");
- urlConn.setUseCaches(false);
- urlConn.setInstanceFollowRedirects(true);
- urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
- urlConn.setRequestProperty("Charset", "UTF-8");
- urlConn.connect();
- DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
- Iterator<String> iterator=params.keySet().iterator();
- while(iterator.hasNext()){
- String key= iterator.next();
- String value= URLEncoder.encode(params.get(key),"UTF-8");
- out.write((key+"="+value+"&").getBytes());
- }
- out.flush();
- out.close();
- int resCode=urlConn.getResponseCode();
- if(resCode!=HTTP_STATUS_REULTOK){
- msg.what=HTTP_STATUS_NORESP;
- msg.obj=resCode;
- handler.sendMessage(msg);
- return ;
- }
- String result="";
- String readLine=null;
- InputStreamReader inputStream=new InputStreamReader(urlConn.getInputStream());
- BufferedReader bufferReader=new BufferedReader(inputStream);
- while((readLine=bufferReader.readLine())!=null){
- result+=readLine;
- }
- msg.what=HTTP_STATUS_REULTOK;
- msg.obj=URLDecoder.decode(result,"UTF-8");
- inputStream.close();
- bufferReader.close();
- urlConn.disconnect();
- }catch(Exception ex){
- msg.what=HTTP_STATUS_ERROR;
- msg.obj=ex.getMessage().toString()+".";
- }
- finally{
- handler.sendMessage(msg);
- }
- }
- }.start();
- }
- /**
- * 自定义文字和文件传输协议[示例在函数结尾];
- * @param apiUrl api地址
- * @param mapParams 文字字段参数
- * @param listUpFiles 多文件参数
- * @param callBack 返回调用;
- */
- public static void post2(final String apiUrl,final HashMap<String,String> mapParams,final ArrayList<ConnInternetUploadFile> listUpFiles,ConnInternetCallback callBack){
- final Handler handler=getHandle(apiUrl, callBack);
- new Thread(new Runnable() {
- public void run() {
- Message msg=handler.obtainMessage(HTTP_STATUS_START, "开始连接");
- String BOUNDARY="———7d4a6454354fe54scd";
- String PREFIX="--";
- String LINE_END="\r\n";
- try{
- URL url=new URL(apiUrl);
- HttpURLConnection urlConn=(HttpURLConnection) url.openConnection();
- urlConn.setDoOutput(true);
- urlConn.setDoInput(true);
- urlConn.setUseCaches(false);
- urlConn.setRequestMethod("POST");
- urlConn.setRequestProperty("Connection", "Keep-Alive");
- urlConn.setRequestProperty("Charset", "UTF-8");
- urlConn.setRequestProperty("Content-Type","multipart/form-data ;boundary="+BOUNDARY);
- DataOutputStream outStream=new DataOutputStream(urlConn.getOutputStream());
- for(Map.Entry<String,String> entry:mapParams.entrySet()){
- StringBuilder sbParam=new StringBuilder();
- sbParam.append(PREFIX);
- sbParam.append(BOUNDARY);
- sbParam.append(LINE_END);
- sbParam.append("Content-Disposition:form-data;name=\""+ entry.getKey()+"\""+LINE_END);
- sbParam.append("Content-Transfer-Encoding: 8bit" + LINE_END);
- sbParam.append(LINE_END);
- sbParam.append(entry.getValue());
- sbParam.append(LINE_END);
- outStream.write(sbParam.toString().getBytes());
- }
- for(ConnInternetUploadFile file:listUpFiles){
- StringBuilder sbFile=new StringBuilder();
- sbFile.append(PREFIX);
- sbFile.append(BOUNDARY);
- sbFile.append(LINE_END);
- sbFile.append("Content-Disposition:form-data;name=\""+file.getFormname()+"\";filename=\""+file.getFileName()+"\""+LINE_END);
- sbFile.append("Content-type:"+file.getContentType()+"\""+LINE_END);
- outStream.write(sbFile.toString().getBytes());
- writeFileToOutStream(outStream,file.getFileUrl());
- outStream.write(LINE_END.getBytes("UTF-8"));
- }
- byte[] end_data=(PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes("UTF-8");
- outStream.write(end_data);
- outStream.flush();
- outStream.close();
- int resCode=urlConn.getResponseCode();
- if(resCode!=HTTP_STATUS_REULTOK){
- msg.what=HTTP_STATUS_NORESP;
- msg.obj=resCode;
- handler.sendMessage(msg);
- return ;
- }
- String result="";
- String readLine=null;
- InputStreamReader inputStream=new InputStreamReader(urlConn.getInputStream());
- BufferedReader bufferReader=new BufferedReader(inputStream);
- while((readLine=bufferReader.readLine())!=null){
- result+=readLine;
- }
- msg.what=HTTP_STATUS_REULTOK;
- msg.obj=URLDecoder.decode(result,"UTF-8");
- inputStream.close();
- bufferReader.close();
- urlConn.disconnect();
- }catch(Exception ex){
- msg.what=HTTP_STATUS_ERROR;
- msg.obj=ex.getMessage().toString();
- }
- finally{
- handler.sendMessage(msg);
- }
- }
- }).start();
- // HashMap<String,String> params=new HashMap<String, String>();
- // params.put("pid", fileHelper.getShareProf("PassportId"));
- // params.put("json",postJson(text));
- // ArrayList<UploadFile> uploadFiles=new ArrayList<UploadFile>();
- // if(url.length()>0){
- // UploadFile upfile=new UploadFile(url,url,"Images");
- // uploadFiles.add(upfile);
- // }
- // Internet.post(Api.api_messageCreate, params,uploadFiles,new InternetCallback() {
- // @Override
- // public void callBack(int msgWhat, String api, String result) {
- // if(msgWhat==Internet.HTTP_STATUS_OK){
- // //跟新数据
- // adapter.notifyDataSetChanged();
- // //显示没有数据
- // }else showToast("网络错误");
- // }
- // });
- }
- /**
- * 第三方Apache集成POST
- * @param url api地址
- * @param mapParams 参数
- * @param callBack
- */
- public static void post3(final String url, final HashMap<String,String> mapParams,final HashMap<String,String> mapFileInfo,ConnInternetCallback callBack) {
- final Handler handler=getHandle(url , callBack);
- new Thread() {
- @Override
- public void run() {
- Message msg=handler.obtainMessage(HTTP_STATUS_START, "开始连接");
- try {
- HttpPost httpPost = new HttpPost(url);
- //多类型;
- MultipartEntity multipartEntity = new MultipartEntity();
- //字段
- Iterator<?> it=mapParams.keySet().iterator();
- while(it.hasNext()){
- String key=(String) it.next();
- String value=mapParams.get(key);
- multipartEntity.addPart(key,new StringBody(value,Charset.forName("UTF-8")));
- }
- //文件
- it=mapFileInfo.keySet().iterator();
- while(it.hasNext()){
- String key=(String)it.next();
- String value=mapFileInfo.get(key);
- multipartEntity.addPart(key, new FileBody(new File(value)));
- }
- httpPost.setEntity(multipartEntity);
- HttpClient httpClient = new DefaultHttpClient();
- HttpResponse httpResp = httpClient.execute(httpPost);
- int resCode=httpResp.getStatusLine().getStatusCode();
- if(resCode!=HTTP_STATUS_REULTOK){
- msg.what=HTTP_STATUS_NORESP;
- msg.obj=resCode;
- handler.sendMessage(msg);
- return ;
- }
- msg.what=HTTP_STATUS_REULTOK;
- msg.obj= EntityUtils.toString(httpResp.getEntity());
- }catch (Exception e) {
- msg.what=HTTP_STATUS_ERROR;
- msg.obj= e.getMessage();
- }
- finally{
- handler.sendMessage(msg);
- }
- }
- }.start();
- }
- public static Bitmap loadBitmapFromNet(String imgUrl,BitmapFactory.Options options){
- Bitmap bitmap = null;
- URL imageUrl = null;
- if (imgUrl == null || imgUrl.length() == 0) return null;
- try {
- imageUrl = new URL(imgUrl);
- URLConnection conn = imageUrl.openConnection();
- conn.setDoInput(true);
- conn.connect();
- InputStream is = conn.getInputStream();
- int length = conn.getContentLength();
- if (length != -1) {
- byte[] imgData = new byte[length];
- byte[] temp = new byte[512];
- int readLen = 0;
- int destPos = 0;
- while ((readLen = is.read(temp)) != -1) {
- System.arraycopy(temp, 0, imgData, destPos, readLen);
- destPos += readLen;
- }
- bitmap = BitmapFactory.decodeByteArray(imgData, 0, imgData.length,options);
- options.inJustDecodeBounds=false;
- bitmap = BitmapFactory.decodeByteArray(imgData, 0, imgData.length,options);
- }
- } catch (IOException e) {
- return null;
- }
- return bitmap;
- }
- public static void writeFileToOutStream(DataOutputStream outStream,String url){
- try {
- InputStream inputStream = new FileInputStream(new File(url));
- int ch;
- while((ch=inputStream.read())!=-1){
- outStream.write(ch);
- }
- inputStream.close();
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- public interface ConnInternetCallback{
- public void callBack(int msgWhat,String api,String result);
- }
- public class ConnInternetUploadFile {
- private String filename;
- private String fileUrl;
- private String formname;
- private String contentType = "application/octet-stream";
- //image/jpeg
- public ConnInternetUploadFile(String filename, String fileUrl, String formname) {
- this.filename = filename;
- this.fileUrl=fileUrl;
- this.formname = formname;
- }
- public String getFileUrl() {
- return fileUrl;
- }
- public void setFileUrl(String url) {
- this.fileUrl=url;
- }
- public String getFileName() {
- return filename;
- }
- public void setFileName(String filename) {
- this.filename = filename;
- }
- public String getFormname() {
- return formname;
- }
- public void setFormname(String formname) {
- this.formname = formname;
- }
- public String getContentType() {
- return contentType;
- }
- public void setContentType(String contentType) {
- this.contentType = contentType;
- }
- }
- }
2.Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件
简单的 Android 拍照并显示以及获取路径后上传
Activity 中的代码,我只贴出重要的事件部分代码
- public void doPhoto(View view)
- {
- destoryBimap();
- String state = Environment.getExternalStorageState();
- if (state.equals(Environment.MEDIA_MOUNTED)) {
- Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
- startActivityForResult(intent, 1);
- } else {
- Toast.makeText(MainActivity.this, "没有SD卡", Toast.LENGTH_LONG).show();
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data)
- {
- Uri uri = data.getData();
- if (uri != null) {
- this.photo = BitmapFactory.decodeFile(uri.getPath());
- }
- if (this.photo == null) {
- Bundle bundle = data.getExtras();
- if (bundle != null) {
- this.photo = (Bitmap) bundle.get("data");
- } else {
- Toast.makeText(MainActivity.this, "拍照失败", Toast.LENGTH_LONG).show();
- return;
- }
- }
- FileOutputStream fileOutputStream = null;
- try {
- // 获取 SD 卡根目录
- String saveDir = Environment.getExternalStorageDirectory() + "/meitian_photos";
- // 新建目录
- File dir = new File(saveDir);
- if (! dir.exists()) dir.mkdir();
- // 生成文件名
- SimpleDateFormat t = new SimpleDateFormat("yyyyMMddssSSS");
- String filename = "MT" + (t.format(new Date())) + ".jpg";
- // 新建文件
- File file = new File(saveDir, filename);
- // 打开文件输出流
- fileOutputStream = new FileOutputStream(file);
- // 生成图片文件
- this.photo.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
- // 相片的完整路径
- this.picPath = file.getPath();
- ImageView imageView = (ImageView) findViewById(R.id.showPhoto);
- imageView.setImageBitmap(this.photo);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (fileOutputStream != null) {
- try {
- fileOutputStream.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * 销毁图片文件
- */
- private void destoryBimap()
- {
- if (photo != null && ! photo.isRecycled()) {
- photo.recycle();
- photo = null;
- }
- }
Layout 布局页面
- <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/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>
折腾了好几天的 HTTP 终于搞定了,经测试正常,不过是初步用例测试用的,因为后面还要修改先把当前版本保存在博客里吧。
其中POST因为涉及多段上传需要导入两个包文件,我用的是最新的 httpmine4.3 发现网上很多 MultipartEntity 相关的文章都是早起版本的,以前的一些方法虽然还可用,但新版本中已经不建议使用了,所以全部使用新的方式 MultipartEntityBuilder 来处理了。
- httpmime-4.3.2.jar
- httpcore-4.3.1.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 = 5000;
- protected int soTimeout = 10000;
- protected int statusCode = 200;
- 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[1024];
- int len = -1;
- while ((len = inStream.read(buf)) != -1) {
- baos.write(buf, 0, 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>
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);