Android HTTP Client: GET, POST, Download, Upload, Multipart Request

Android 的 HTTP 客户端:GET, POST, Download, Upload, Multipart Req...

英文原文:Android HTTP Client: GET, POST, Download, Upload, Multipart Request

标签:  Android
0人收藏此文章, 我要收藏 oschina 推荐于 14天前 (共 4 段, 翻译完成于 05-22) ( 0评
参与翻译(1人)

Android应用通常都要和远程服务器进行交互。最简单的方式是使用基于HTTP协议来传输信息。在一些场景里HTTP协议是非常有用的,就像从远程服务器下载一个图像或者上传一些二进制数据到服务器。Android应用程序使用GET或POST请求来发送数据。在这篇文章,我们想要分析怎样用HttpURLConnection来和一个远程服务器通信。

我们包含这3个主要主题:

  • GET 和POST 请求
  • 从远程服务器下载数据
  • 使用MultipartRequest上传数据到服务器
我们会用运行在Tomcat7.0里的3个简单Servlet来作为一个简单的服务器。我们不会讲到怎样使用API3.0来创建Servlet但源代码现在就会提供。
throwable
throwable
翻译于 14天前

0人顶

 翻译的不错哦!

GET 和POST 请求

GET和POST是HTTP协议里的基本模块。要使用这些类型的请求,我们首先需要打开一个连接到远程服务器连接: 
1 HttpURLConnection con = (HttpURLConnection) ( new URL(url)).openConnection();
2 con.setRequestMethod("POST");
3 con.setDoInput(true);
4 con.setDoOutput(true);
5 con.connect();

我们在第一行得到HttpURLConnection,而在第二行我们设置了方法同时在最后连接到服务器。

一旦我们打开了连接,我们使用OutputStream在它上面写入东西。

1 con.getOutputStream().write( ("name=" + name).getBytes());

我们已经知道参数是用键-值对来写入。

最后一步是使用InputStream读取返回。

1 InputStream is = con.getInputStream();
2 byte[] b = new byte[1024];
3 while ( is.read(b) != -1)
4   buffer.append(new String(b));
5 con.disconnect();
现在所有东西都非常简单,但我们要记住一件事情:创建一个HTTP连接比较耗时的操作,有时候可能需要很长时间所以我们不能在主线程里运行它,否则我们会得到一个ANR  (Application Not Responding)问题。要解决这个问题,我们可以用一个AsyncTask。 
01 private class SendHttpRequestTask extends AsyncTask<String, Void, String>{
02    
03   @Override
04   protected String doInBackground(String... params) {
05    String url = params[0];
06    String name = params[1];
07    String data = sendHttpRequest(url, name);
08    return data;
09   }
10  
11   @Override
12   protected void onPostExecute(String result) {
13    edtResp.setText(result);
14    item.setActionView(null);  
15   }
16 }
运行APP我们得到了: 

android_httpclient_post_get_1android_httpclient_post_get_2

我们可以看到传了一个name到服务器同时它回复了一个典型的“Hello...”。在服务器端我们可以检查服务器是否正确接收到我们传递的参数。 

android_tomcat_post_log 
throwable
throwable
翻译于 14天前

0人顶

 翻译的不错哦!

从服务器下载数据

最常见的场景之一是一个Android APp需要从一个远程服务器下载一些数据。我们假设我们需要从服务器下载一个图片。在这种情况下我们就总得使用  AsyncTask来完成我们的操作,代码如下:  
01 public byte[] downloadImage(String imgName) {
02     ByteArrayOutputStream baos = new ByteArrayOutputStream();
03     try {
04         System.out.println("URL ["+url+"] - Name ["+imgName+"]");
05          
06         HttpURLConnection con = (HttpURLConnection) ( new URL(url)).openConnection();
07         con.setRequestMethod("POST");
08         con.setDoInput(true);
09         con.setDoOutput(true);
10         con.connect();
11         con.getOutputStream().write( ("name=" + imgName).getBytes());
12          
13         InputStream is = con.getInputStream();
14         byte[] b = new byte[1024];
15          
16         while ( is.read(b) != -1)
17             baos.write(b);
18          
19         con.disconnect();
20     }
21     catch(Throwable t) {
22         t.printStackTrace();
23     }
24      
25     return baos.toByteArray();
26 }
这个方法用下面的方式来调用: 
01 private class SendHttpRequestTask extends AsyncTask<String, Void, byte[]> {
02  
03      
04     @Override
05     protected byte[] doInBackground(String... params) {
06         String url = params[0];
07         String name = params[1];
08          
09         HttpClient client = new HttpClient(url);
10         byte[] data = client.downloadImage(name);
11          
12         return data;
13     }
14  
15     @Override
16     protected void onPostExecute(byte[] result) {
17         Bitmap img = BitmapFactory.decodeByteArray(result, 0, result.length);
18         imgView.setImageBitmap(img);
19         item.setActionView(null);
20          
21     }
22     
23 }
运行我们的App: 

android_httpclient_post_download 
throwable
throwable
翻译于 14天前

0人顶

 翻译的不错哦!

使用MultipartRequest来上传数据到服务器

这是处理http连接里最复杂的部分。原生的HttpURLConnection不处理这类型的请求。它发生在一个Android App要上传一些二进制数据到服务器。它也可能是一个app上传一个图片。在这种情况下,请求会更加复杂,因为一个“普通”的请求并不足够。我们要创建一个MultipartRequest。

一个MultipartRequest是由各种不同部分组成的请求,就像参数和二进制数据。我们要怎样去处理这些请求呢?

第一部就是打开一个连接告诉服务器我们想传递一些二进制信息:

01 public void connectForMultipart() throws Exception {
02     con = (HttpURLConnection) ( new URL(url)).openConnection();
03     con.setRequestMethod("POST");
04     con.setDoInput(true);
05     con.setDoOutput(true);
06     con.setRequestProperty("Connection""Keep-Alive");
07     con.setRequestProperty("Content-Type""multipart/form-data; boundary=" + boundary);
08     con.connect();
09     os = con.getOutputStream();
10 }

在第6行和第7行,我们指定了请求的content-type和另外一个叫boundary的字段。这个字段是一个字符串序列来分割不同部分的。

对于我们要加入的每个部分,我们需要指定它否是一个文本部分就像post参数或者它是一个而文件(二进制数据)。

01 public void addFormPart(String paramName, String value) throws Exception {
02   writeParamData(paramName, value);
03 }
04  
05 private void writeParamData(String paramName, String value) throws Exception {
06     os.write( (delimiter + boundary + "\r\n").getBytes());
07     os.write( "Content-Type: text/plain\r\n".getBytes());
08     os.write( ("Content-Disposition: form-data; name=\"" + paramName + "\"\r\n").getBytes());;
09     os.write( ("\r\n" + value + "\r\n").getBytes());
10      
11 }
这里  
1 private String delimiter = "--";
2 private String boundary =  "SwA"+Long.toString(System.currentTimeMillis())+"SwA";
加入一个文件我们能够这样使用: 
01 public void addFilePart(String paramName, String fileName, byte[] data) throws Exception {
02     os.write( (delimiter + boundary + "\r\n").getBytes());
03     os.write( ("Content-Disposition: form-data; name=\"" + paramName +  "\"; filename=\""+ fileName + "\"\r\n"  ).getBytes());
04     os.write( ("Content-Type: application/octet-stream\r\n"  ).getBytes());
05     os.write( ("Content-Transfer-Encoding: binary\r\n"  ).getBytes());
06     os.write("\r\n".getBytes());
07     
08     os.write(data);
09      
10     os.write("\r\n".getBytes());
11 }
因此在我们的App里就这样: 
01 private class SendHttpRequestTask extends AsyncTask<String, Void, String> {
02  
03      
04     @Override
05     protected String doInBackground(String... params) {
06         String url = params[0];
07         String param1 = params[1];
08         String param2 = params[2];
09         Bitmap b = BitmapFactory.decodeResource(UploadActivity.this.getResources(), R.drawable.logo);
10          
11         ByteArrayOutputStream baos = new ByteArrayOutputStream();
12         b.compress(CompressFormat.PNG, 0, baos);
13  
14         try {
15             HttpClient client = new HttpClient(url);
16             client.connectForMultipart();
17             client.addFormPart("param1", param1);
18             client.addFormPart("param2", param2);
19             client.addFilePart("file""logo.png", baos.toByteArray());
20             client.finishMultipart();
21             String data = client.getResponse();
22         }
23         catch(Throwable t) {
24             t.printStackTrace();
25         }
26          
27         return null;
28     }
29  
30     @Override
31     protected voidonPostExecute(String data) {           
32         item.setActionView(null);       
33     }
34     
35 }
运行它我们就看到: 

android_tomcat_post_upload_logandroid_httpclient_post_upload
源代码 @  github.
throwable
throwable
翻译于 14天前

0人顶

 翻译的不错哦!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值