Android系列之网络(三)----使用HttpClient发送HTTP请求(分别通过GET和POST方法发送数据)

简介:

【正文】

在前两篇文章中,我们学习到了和HTTP相关的基础知识。文章链接如下:

Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)

Android系列之网络(二)----HTTP请求头与响应头

一、GET和POST的对比:

在漫长的时间当中,其他的方法逐渐的退出了历史舞台,最常用的只剩下GET和POST方法。而之前已经讲过了通过GET方法获取数据,今天来学习一下如何分别通过GET和POST获取数据。

举个例子:get类似于明信片,只有请求头,没有请求体。而post类似于一封信,信封上的内容为请求头;信里面的内容为请求体(请求头和请求体是分开的)。

含义如下:

  • GET:通过请求URI得到资源。一般用于获取/查询资源信息。
  • POST:用于向服务器提交新的内容。一般用于更新资源信息。

主要区别如下:

  • GET方法主要用于从服务器取回数据,POST用于向服务器提交数据
  • get类似于明信片,只有请求头,没有请求体;post类似于一封信,信封上的内容为请求头;信里面的内容为请求体
  • 使用GET方法啊向服务器i教的数据量较小,通常不超过2K,使用POST向服务器提交的数据量通常没有限制(明信片不能多写,而写信可以写好多内容咧)
  • GET请求是将所要提交的数据附在URL之后,而POST请求是将提交的数据放置在请求体当中

老罗在将到get和post请求的时候, 是这样说的:

  • 1、GET是从服务器上获取数据,POST是向服务器传送数据。
  • 2、在客户端, GET方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交
  • 3、对于GET方式,服务器端用Request.QueryString获取变量的值,对于POST方式,服务器端用Request.Form获取提交的数据。
  • 4、GET方式提交的数据最多只能有1024字节,而POST则没有此限制
  • 5、安全性问题。正如在(2)中提到,使用 GET 的时候,参数会显示在地址栏上,而 POST 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 GET ;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 POST为好

啰嗦了这么多,对这段来个总结吧。

 【总结】

get/post请求的区别:

  • get请求方式:显式请求方式,请求参数会在URL上显示,相对快,安全性较低,请求数据的大小一般不超过1kb。
  • post请求方式:隐式请求方式,请求参数将会在http请求的实体内容中进行传输,相对慢,安全性较高 ,请求数据的大小没有限制

注:GET请求方式和POST请求区别在于请求参数在传递的过程中方式不同。

 

二、URL的定义和组成:

URL:Uniform Resource Locator 统一资源定位符

URL的组成部分:以http://www.mbalib.com/china/index.htm为例

  • http://:代表超文本传输协议
  • www:代表一个万维网服务器
  • mbalib.com/:服务器的域名,或服务器名称
  • China/:子目录,类似于我们的文件夹
  • Index.htm:是文件夹中的一个文件
  • /china/index.htm统称为URL路径

 

三、使用tomcat软件在本地搭建服务器:

有了这个服务器,就相当于在本地的计算机有了一个网站,然后我们可以通过浏览器来访问这个网站。

tomcat软甲是apache旗下的一个开源项目。软件下载链接:http://tomcat.apache.org/

下载之后,将压缩包解压:

注意目录名不能有中文和空格。

软件运行之前要保证环境变量已经配置:

上图中,变量名为JAVA_HOME,变量值为:JDK安装的绝对路径。

回到tomcat的bin目录中, 双击startup.bat:

之后弹出如下界面:

这个时候,本地的服务器就已经搭建起来了。

首先查看自己电脑的ip地址,我的计算机的ip地址为:192.168.1.112。

在浏览器中输入http://192.168.1.112:8080/。如果弹出如下界面,表示tomcat安装成功并且启动起来了:

上方图片中,显示我的Tomcat的版本为:8.0.14。它的版本号是跟着JDK的版本走的,所以,建议JDK的版本为1.8。

我们现在在浏览器上测试一下它吧:

首先在D:\apache-tomcat-8.0.14\webapps\ROOT目录中新建一个jsp文件:

jsp文件中填入如下内容:

复制代码
<%

String name = request.getParameter("name");

String pwd = request.getParameter("password");

 

out.print("name:" + name + ",password:" + pwd); //在浏览器上显示输入地址中的用户名与密码

%>
复制代码

现在我们随便起一个用户名和密码的账号,比如用户名smyhvae,密码为smyh,然后在浏览器中输入如下内容:

http://192.168.1.112:8080/test.jsp?name=smyhvae&password=smyh

输入这个链接之后,回车,出现如下界面:

上图中表示,我们向服务器发送这样一个请求,链接中,问号前面的内容代表请求的路径,问号后面是我们要传送的参数(键是固定不变的,值是用户自己填写的),然后服务器返还给我们这样的数据。

 

四、使用GET方法向服务器发送数据:

我们在博客“Android系列之网络(一)”中其实就已经通过GET方法向服务器获取数据了,只不过那篇文章中是访问百度首页,然后获取百度首页的数据。现在我们要通过同样的GET方法,只不过是换成了获取本地服务器搭建的网站数据。

只需要稍微修改一下那篇文章中的代码(代码结构一样,只是换了另外一个链接)。完整版代码如下:

activity_main.xml:

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText 
        android:id="@+id/nameText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="username" />
    
    <EditText 
        android:id="@+id/pwdText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="password" />

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="submit" />

</LinearLayout>
复制代码

MainActivity.java的代码如下:

复制代码
 1 package com.example.m04_http02;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.InputStreamReader;
 5 import java.util.ArrayList;
 6 import org.apache.http.HttpEntity;
 7 import org.apache.http.HttpResponse;
 8 import org.apache.http.NameValuePair;
 9 import org.apache.http.client.HttpClient;
10 import org.apache.http.client.entity.UrlEncodedFormEntity;
11 import org.apache.http.client.methods.HttpGet;
12 import org.apache.http.client.methods.HttpPost;
13 import org.apache.http.impl.client.DefaultHttpClient;
14 import org.apache.http.message.BasicNameValuePair;
15 
16 import android.app.Activity;
17 import android.os.Bundle;
18 import android.util.Log;
19 import android.view.View;
20 import android.view.View.OnClickListener;
21 import android.widget.Button;
22 import android.widget.EditText;
23 
24 public class MainActivity extends Activity {
25 
26     private EditText nameText;
27     private EditText pwdText;
28     private Button button;
29 
30     @Override
31     protected void onCreate(Bundle savedInstanceState) {
32         super.onCreate(savedInstanceState);
33         setContentView(R.layout.activity_main);
34         nameText = (EditText) findViewById(R.id.nameText);
35         pwdText = (EditText) findViewById(R.id.pwdText);
36         button = (Button) findViewById(R.id.button1);
37 
38         button.setOnClickListener(new OnClickListener() {
39 
40             @Override
41             public void onClick(View v) {
42                 // TODO Auto-generated method stub
43                 // 用户输入用户名密码, 然后通过Get方法发送给本地服务器
44                 String name = nameText.getText().toString();
45                 String pwd = pwdText.getText().toString();
46 
47                 // 运行线程,使用GET方法向本地服务器发送数据
48                 GetThread getThread = new GetThread(name, pwd);
49                 getThread.start();
50             }
51         });
52     }
53     
54     //子线程:通过GET方法向服务器发送用户名、密码的信息
55     class GetThread extends Thread {
56 
57         String name;
58         String pwd;
59 
60         public GetThread(String name, String pwd) {
61             this.name = name;
62             this.pwd = pwd;
63         }
64 
65         @Override
66         public void run() {
67             //用HttpClient发送请求,分为五步
68             //第一步:创建HttpClient对象
69             HttpClient httpClient = new DefaultHttpClient();
70             //注意,下面这一行中,我之前把链接中的"test"误写成了"text",导致调BUG调了半天没弄出来,真是浪费时间啊
71             String url = "http://192.168.1.112:8080/test.jsp?name=" + name+ "&password=" + pwd;
72             //第二步:创建代表请求的对象,参数是访问的服务器地址
73             HttpGet httpGet = new HttpGet(url);
74             try {
75                 //第三步:执行请求,获取服务器发还的相应对象
76                 HttpResponse response = httpClient.execute(httpGet);
77                 //第四步:检查相应的状态是否正常:检查状态码的值是200表示正常
78                 if (response.getStatusLine().getStatusCode() == 200) {
79                     //第五步:从相应对象当中取出数据,放到entity当中
80                     HttpEntity entity = response.getEntity();
81                     BufferedReader reader = new BufferedReader(
82                             new InputStreamReader(entity.getContent()));
83                     String result = reader.readLine();
84                     Log.d("HTTP", "GET:" + result);
85                 }
86             } catch (Exception e) {
87                 e.printStackTrace();
88             }
89 
90         }
91     }
92 } 
复制代码

上方代码中,第73行就是我们所放入的url链接。运行程序后,输入用户名密码,可以看到在后台打印出了我们所输入的用户名和密码:

   

五、使用POST方法向服务器发送数据:

上一段中,我们是通过GET方法向服务器发送数据,现在通过POST方法向服务器发送数据。布局文件的代码不变,就不写了。MainActivity.java的代码如下:

复制代码
  1 package com.example.m04_http02;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.InputStreamReader;
  5 import java.util.ArrayList;
  6 
  7 import org.apache.http.HttpEntity;
  8 import org.apache.http.HttpResponse;
  9 import org.apache.http.NameValuePair;
 10 import org.apache.http.client.HttpClient;
 11 import org.apache.http.client.entity.UrlEncodedFormEntity;
 12 import org.apache.http.client.methods.HttpGet;
 13 import org.apache.http.client.methods.HttpPost;
 14 import org.apache.http.impl.client.DefaultHttpClient;
 15 import org.apache.http.message.BasicNameValuePair;
 16 
 17 import android.app.Activity;
 18 import android.os.Bundle;
 19 import android.util.Log;
 20 import android.view.View;
 21 import android.view.View.OnClickListener;
 22 import android.widget.Button;
 23 import android.widget.EditText;
 24 
 25 public class MainActivity extends Activity {
 26 
 27     private EditText nameText;
 28     private EditText pwdText;
 29     private Button button;
 30 
 31     @Override
 32     protected void onCreate(Bundle savedInstanceState) {
 33         super.onCreate(savedInstanceState);
 34         setContentView(R.layout.activity_main);
 35         nameText = (EditText) findViewById(R.id.nameText);
 36         pwdText = (EditText) findViewById(R.id.pwdText);
 37         button = (Button) findViewById(R.id.button1);
 38 
 39         button.setOnClickListener(new OnClickListener() {
 40 
 41             @Override
 42             public void onClick(View v) {
 43                 // TODO Auto-generated method stub
 44                 // 用户输入用户名密码, 然后通过Get方法发送给本地服务器
 45                 String name = nameText.getText().toString();
 46                 String pwd = pwdText.getText().toString();
 47 
 48                 // 使用GET方法向本地服务器发送数据
 49                 //GetThread getThread = new GetThread(name, pwd);
 50                 //getThread.start();                
 51                 
 52                 //使用POST方法向服务器发送数据
 53                 PostThread postThread = new PostThread(name, pwd);
 54                 postThread.start();
 55             }
 56         });
 57     }
 58 
 59 
 60     //子线程:通过GET方法向服务器发送用户名、密码的信息
 61     class GetThread extends Thread {
 62 
 63         String name;
 64         String pwd;
 65 
 66         public GetThread(String name, String pwd) {
 67             this.name = name;
 68             this.pwd = pwd;
 69         }
 70 
 71         @Override
 72         public void run() {
 73             //用HttpClient发送请求,分为五步
 74             //第一步:创建HttpClient对象
 75             HttpClient httpClient = new DefaultHttpClient();
 76             //注意,下面这一行中,我之前把链接中的"test"误写成了"text",导致调BUG调了半天没弄出来,真是浪费时间啊
 77             String url = "http://192.168.1.112:8080/test.jsp?name=" + name+ "&password=" + pwd;
 78             //第二步:创建代表请求的对象,参数是访问的服务器地址
 79             HttpGet httpGet = new HttpGet(url);
 80             try {
 81                 //第三步:执行请求,获取服务器发还的相应对象
 82                 HttpResponse response = httpClient.execute(httpGet);
 83                 //第四步:检查相应的状态是否正常:检查状态码的值是200表示正常
 84                 if (response.getStatusLine().getStatusCode() == 200) {
 85                     //第五步:从相应对象当中取出数据,放到entity当中
 86                     HttpEntity entity = response.getEntity();
 87                     BufferedReader reader = new BufferedReader(
 88                             new InputStreamReader(entity.getContent()));
 89                     String result = reader.readLine();
 90                     Log.d("HTTP", "GET:" + result);
 91                 }
 92             } catch (Exception e) {
 93                 e.printStackTrace();
 94             }
 95 
 96         }
 97     }    
 98     
 99     //子线程:使用POST方法向服务器发送用户名、密码等数据
100     class PostThread extends Thread {
101 
102         String name;
103         String pwd;
104 
105         public PostThread(String name, String pwd) {
106             this.name = name;
107             this.pwd = pwd;
108         }
109 
110         @Override
111         public void run() {
112             HttpClient httpClient = new DefaultHttpClient();
113             String url = "http://192.168.1.112:8080/test.jsp";
114             //第二步:生成使用POST方法的请求对象
115             HttpPost httpPost = new HttpPost(url);
116             //NameValuePair对象代表了一个需要发往服务器的键值对
117             NameValuePair pair1 = new BasicNameValuePair("name", name);
118             NameValuePair pair2 = new BasicNameValuePair("password", pwd);
119             //将准备好的键值对对象放置在一个List当中
120             ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
121             pairs.add(pair1);
122             pairs.add(pair2);
123             try {
124                 //创建代表请求体的对象(注意,是请求体)
125                 HttpEntity requestEntity = new UrlEncodedFormEntity(pairs);
126                 //将请求体放置在请求对象当中
127                 httpPost.setEntity(requestEntity);
128                 //执行请求对象
129                 try {
130                     //第三步:执行请求对象,获取服务器发还的相应对象
131                     HttpResponse response = httpClient.execute(httpPost);
132                     //第四步:检查相应的状态是否正常:检查状态码的值是200表示正常
133                     if (response.getStatusLine().getStatusCode() == 200) {
134                         //第五步:从相应对象当中取出数据,放到entity当中
135                         HttpEntity entity = response.getEntity();
136                         BufferedReader reader = new BufferedReader(
137                                 new InputStreamReader(entity.getContent()));
138                         String result = reader.readLine();
139                         Log.d("HTTP", "POST:" + result);
140                     }
141                 } catch (Exception e) {
142                     e.printStackTrace();
143                 }
144             } catch (Exception e) {
145                 e.printStackTrace();
146             }
147         }
148     }
149     
150     
151 }
复制代码

上方代码中,我们新开一个子线程,使用POST方法向服务器发送用户名、密码等数据。我们之前已经知道,使用GET方法发送HTTP请求有五大步骤,而如今换成POST方法时,需要在第二步和第三步之间加入一些步骤即上方加粗部分的代码:116-127行),多的步骤其实是往请求对象中加入请求体。现在来详细解释一下这部分代码:

我们通过NameValuePair集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity当中(这个类的对象就代表了一个请求体,即键值对),然后将请求体放置在请求对象httpPost当中。

程序运行后,输入用户名和密码,点击按钮,在后台打印出了之前输入的用户名密码:

现在我们总结一下POST提交数据的步骤:

  • 1. 构造请求对象;
  • 2. 将需要传递给服务器端的数据放置在键值对对象当中;
  • 3. 将准备好的键值对放置在List当中;
  • 4. 生成代表请求体的对象;
  • 5. 将存有请求键值对的List对象放置在请求题对象当中;
  • 6. 将请求体对象放置到请求对象当中;
  • 7. 发送请求对象
  • 后面的步骤(即处理请求对象)和GET方法是一致的。

上面两段的例子,都是通过GET和POST往服务器发送数据(在此,二者的作用是等价的)。需要注意的是,一般来讲,GET是从服务器取数据,但在此例子中GET却是往服务器发数据。如果是上传文件,就必须用POST。我们将在今后的章节中讲到。

相关文章
|
1月前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin协程优化网络请求处理
【2月更文挑战第30天】 在移动应用开发领域,网络请求的处理是影响用户体验的关键环节。针对Android平台,利用Kotlin协程能够极大提升异步任务处理的效率和简洁性。本文将探讨如何通过Kotlin协程优化Android应用中的网络请求处理流程,包括协程的基本概念、网络请求的异步执行以及错误处理等方面,旨在帮助开发者构建更加流畅和响应迅速的Android应用。
|
8天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
9 0
|
8天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
8 0
|
29天前
|
机器学习/深度学习 存储 供应链
【软件设计师备考 专题 】运算基本方法:预测与决策、线性规划、网络图、模拟
【软件设计师备考 专题 】运算基本方法:预测与决策、线性规划、网络图、模拟
57 0
|
1月前
|
数据采集 缓存 前端开发
http和https请求服务器的时候在请求头部分都带什么到服务器呢?
HTTP和HTTPS请求头基本结构相似,HTTPS多了一层SSL/TLS加密。常见请求头如Accept(指定内容类型)、Authorization(身份验证)、Cookie(会话跟踪)、User-Agent(标识用户代理)等。HTTPS特有的头包括Upgrade-Insecure-Requests(升级到HTTPS)、Strict-Transport-Security(强制使用HTTPS)、Sec-Fetch-*(安全策略)和X-Content-Type-Options、X-Frame-Options等(增强安全性)。实际应用中,请求头会根据需求和安全策略变化。
20 0
|
1月前
|
机器学习/深度学习 存储 算法
6 种 卷积神经网络压缩方法
6 种 卷积神经网络压缩方法
28 0
|
2月前
|
弹性计算 安全 关系型数据库
带你读《从基础到应用云上安全航行指南》——来上课!一文掌握守住ECS网络安全的最佳方法(1)
带你读《从基础到应用云上安全航行指南》——来上课!一文掌握守住ECS网络安全的最佳方法(1)
156 0
|
2月前
|
弹性计算 运维 安全
带你读《从基础到应用云上安全航行指南》——来上课!一文掌握守住ECS网络安全的最佳方法(2)
带你读《从基础到应用云上安全航行指南》——来上课!一文掌握守住ECS网络安全的最佳方法(2)
37 2
|
网络协议 Java 网络安全
【Android 应用开发】Android 网络编程 API笔记 - java.net 包 权限 地址 套接字 相关类 简介(二)
【Android 应用开发】Android 网络编程 API笔记 - java.net 包 权限 地址 套接字 相关类 简介(二)
122 0