Android HTTP 请求方式 HttpClient

淡淡的烟草味﹌ 2022-05-09 04:06 411阅读 0赞

环境准备

  • Java 开发时,后台的 Http 请求操作通常使用的是 org.apache.http.client.HttpClient,Android 开发同样可以使用这些第三方 API。
  • 单纯就使用 Apache 的 HttpCLient 来说,Android 编码 与 Java 编码中 API 使用都是基本一样。

2015-12-01_565daade732eb.jpg

HttpClient 依赖

  • 本人使用的是 Android Studio 3.1.2,第一步就是需要导入 Apache 的 HttpClient 依赖。

70

70 1

70 2

  • 上面是在线下载依赖的方式,如果不能翻墙的,也可以直接和 Java 编程一样,将下载好的 Jar 包手动添加进项目的 libs 目录中

70 3

被请求的服务器

  • 现在开启一个用于被 Android 请求的服务端地址,本人使用 IDEA 新建一个 Spring Boot 项目来做 web 服务端。

70 4

70 5

Android Http get 请求

  • 效果图如下所示,点击按钮开始进行 get 请求,请求成功时如下左图所示,之后关闭 web 服务器端,再次请求时如右图所示,显然连接失败。

70 6

70 7

  • 布局文件 activity_main.xml 文件内容如下:



  • Http 操作的帮助类/工具类内容如下:

    package com.lct.www.yuan.helper;

    import android.util.Log;

    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    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.util.EntityUtils;

    import java.io.IOException;

    /**

    • Http 帮助类
      */
      public class HttpHelper {

      /**

      • http get 请求
        /
        public static String httpGetRequest() {
        /*

        • 设置 Http 请求参数
        • 设置请求超时 20 秒
        • 设置等待数据超时10秒
          /
          HttpParams httpParameters = new BasicHttpParams();
          HttpConnectionParams.setConnectionTimeout(httpParameters, 20
          1000);
          HttpConnectionParams.setSoTimeout(httpParameters, 10 * 1000);
          HttpClient httpclient = new DefaultHttpClient(httpParameters);

          /**

        • 网络访问时 主机地址必须写 域名或者实际 ip 地址
        • 需要注意的是在自己电脑上测试时,服务器也在本机,一不小心就写成了 http://localhost:8080/coco/getTest
        • 或者 127.0.0.1 这种写法会抛异常的
          */
          String uriPath = “http://192.168.1.20:8080/coco/getTest“;
          String result;
          HttpGet httpGet = new HttpGet(uriPath);
          int statusCode = -1;
          try {
          HttpResponse httpResponse = httpclient.execute(httpGet);
          statusCode = httpResponse.getStatusLine().getStatusCode();
          Log.i(“Wmx logs::”, “statusCode=” + statusCode);
          if (statusCode == 200) {//200表示连接成功,403表示拒绝访问
          1. HttpEntity httpEntity = httpResponse.getEntity();
          2. /**获取服务返回的数据*/
          3. result = EntityUtils.toString(httpEntity, "utf-8");
          4. Log.i("Wmx logs::", "result=" + result);
          }
          } catch (ClientProtocolException e) {
          e.printStackTrace();
          return “请求失败,错误代码” + statusCode;
          } catch (IOException e) {
          e.printStackTrace();
          return “请求失败,错误代码” + statusCode;
          } finally {
          /**
          • 操作完成后,关闭连接,释放资源
            */
            if (!httpGet.isAborted()) {
            Log.i(“Wmx logs::”, “abort Client Connection Request”);
            httpGet.abort();
            }
            }
            return “请求成功…”;
            }
            }
  • 主活动 MainActivity.java 文件内容如下:

    package com.lct.www.yuan;

    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;

    import com.lct.www.yuan.helper.HttpHelper;

    public class MainActivity extends AppCompatActivity {

  1. private Button buttonLogin;
  2. /**
  3. * 自定义 Handler 用于 UI 主线程与 http 操作的子线程之间进行通信
  4. */
  5. private Handler myHandler = new Handler() {
  6. /**
  7. * 接收 http 操作的子线程传来的数据
  8. * @param message
  9. */
  10. @Override
  11. public void handleMessage(Message message) {
  12. /**
  13. * android.os.Bundle 就是消息 Message 中的数据
  14. * android.os.BaseBundle#getString(java.lang.String):取值的 key 不存在时,返回 null
  15. * */
  16. Bundle bundle = message.getData();
  17. String messageText = bundle.getString("messageText");
  18. Toast.makeText(getApplicationContext(), messageText, Toast.LENGTH_SHORT).show();
  19. }
  20. };
  21. /**
  22. * 活动被创建时触发
  23. *
  24. * @param savedInstanceState
  25. */
  26. @Override
  27. protected void onCreate(Bundle savedInstanceState) {
  28. Log.i("Wmx logs::", "活动创建...");
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.activity_main);
  31. bindViews();
  32. }
  33. /**
  34. * 视图绑定
  35. */
  36. private void bindViews() {
  37. buttonLogin = findViewById(R.id.buttonLogin);
  38. buttonLogin.setOnClickListener(new View.OnClickListener() {
  39. @Override
  40. public void onClick(View v) {
  41. Log.i("Wmx logs::", "点我.....");
  42. /**
  43. * Android 的网络操作必须新开线程,与 UI 线程分离开来
  44. * 新开线程进行 Http 请求
  45. */
  46. new Thread() {
  47. @Override
  48. public void run() {
  49. Log.i("Wmx logs::", "网络访问新线程=" + Thread.currentThread().getName());
  50. String feedback = HttpHelper.httpGetRequest();
  51. /**将 Http 请求的结果消息传递给 UI 主线程进行显示*/
  52. Message message = myHandler.obtainMessage();
  53. Bundle bundle = message.getData();
  54. bundle.putString("messageText", feedback);
  55. myHandler.sendMessage(message);
  56. }
  57. }.start();
  58. }
  59. });
  60. }
  61. }
  • 因为需要做网络访问,所以必须在全局配置文件 AndroidManifest.xml 中添加权限:

    <?xml version=”1.0” encoding=”utf-8”?>













至此编码完成,控制台输出如下:

I/Wmx logs::: 点我…..
I/Wmx logs::: 网络访问新线程=Thread-1349
I/Wmx logs::: statusCode=200
I/Wmx logs::: result={“message”:”get Test success”}
abort Client Connection Request

  • 后台的 Http get 请求与 web 前端请求后台的 get 请求是一样的,同样可以在请求的时候直接在地址 “?” 后面追加请求参数,多个参数时用 & 符合分隔。
  • 直接可以将参数拼接在地址 “?” 后,如果传递的数据量比较大,建议使用 post 请求,而且对于如果需要发送 中文,则建议先对参数进行编码,否则容易乱码。
  • 其它代码仍然和上面一致,现在在 HttpHelper 中新增一个方法,测试 get 请求的同时传递参数:

    /**

    1. * get 请求的同时传递参数
    2. *
    3. * @return
    4. */
    5. public static String httpGetRunByParam() {
    6. /**对于传递的中文数据,建议先进行 url 编码*/
    7. List<BasicNameValuePair> params = new LinkedList<>();
    8. params.add(new BasicNameValuePair("userName", "华安"));
    9. params.add(new BasicNameValuePair("address", "杭州"));
    10. String param = URLEncodedUtils.format(params, "UTF-8");
    11. /**
    12. * 设置 Http 请求参数
    13. * 设置请求超时 20 秒
    14. * 设置等待数据超时10秒
    15. */
    16. HttpParams httpParameters = new BasicHttpParams();
    17. HttpConnectionParams.setConnectionTimeout(httpParameters, 20 * 1000);
    18. HttpConnectionParams.setSoTimeout(httpParameters, 10 * 1000);
    19. HttpClient httpclient = new DefaultHttpClient(httpParameters);
    20. /**
    21. * 网络访问时 主机地址必须写 域名或者实际 ip 地址
    22. * 需要注意的是在自己电脑上测试时,服务器也在本机,一不小心就写成了 http://localhost:8080/coco/getTest
    23. * 或者 127.0.0.1 这种写法会抛异常的
    24. * 1) get 请求的参数直接拼接在地址的 "?" 后面即可
    25. */
    26. String uriPath = "http://192.168.1.20:8080/coco/getTest?id=9527&" + param;
    27. String result;
    28. HttpGet httpGet = new HttpGet(uriPath);
    29. int statusCode = -1;
    30. HttpResponse httpResponse = null;
    31. try {
    32. httpResponse = httpclient.execute(httpGet);
    33. statusCode = httpResponse.getStatusLine().getStatusCode();
    34. Log.i("Wmx logs::", "statusCode=" + statusCode);
    35. if (statusCode == 200) {//200表示连接成功,403表示拒绝访问
    36. HttpEntity httpEntity = httpResponse.getEntity();
    37. /**获取服务返回的数据*/
    38. result = EntityUtils.toString(httpEntity, "utf-8");
    39. Log.i("Wmx logs::", "result=" + result);
    40. }
    41. } catch (ClientProtocolException e) {
    42. e.printStackTrace();
    43. return "请求失败,错误代码" + statusCode;
    44. } catch (IOException e) {
    45. e.printStackTrace();
    46. return "请求失败,错误代码" + statusCode;
    47. } finally {
    48. /**
    49. * 操作完成后,关闭连接,释放资源
    50. */
    51. if (!httpGet.isAborted()) {
    52. Log.i("Wmx logs::", "abort Client Connection Request");
    53. httpGet.abort();
    54. }
    55. }
    56. return "请求成功...";
    57. }
  • 此时 web 服务器端的请求接口修改如下,获取 Android 中 get 请求传递来的参数:

    /**

    1. * 请求地址:http://localhost:8080/coco/getTest
    2. */
    3. @RequestMapping(value = "getTest")
    4. public void getTest(String id, String userName, String address, HttpServletResponse response) {
    5. try {
    6. System.out.println(new Date() + " 被人家访问了...id=" + id + "\tuserName=" + userName + "\taddress=" + address);
    7. PrintWriter printWriter = response.getWriter();
    8. printWriter.write("{\"message\":\"get Test success\"}");
    9. printWriter.flush();
    10. printWriter.close();
    11. } catch (IOException e) {
    12. e.printStackTrace();
    13. }
    14. }

输出如下:

Sun Sep 30 16:13:02 CST 2018 被人家访问了…id=9527 userName=华安 address=杭州

Android Http post请求

  • post 请求通常用于传递数据,其它代码不变,仍然在HttpHelper 中新增一个方法,测试 post 请求的同时传递参数:

    /*

    1. * post 请求——————通常用于推送数据
    2. *
    3. * @throws IOException
    4. */
    5. public static final String httpPostMessage() {
    6. HttpPost httpPost = null;
    7. String uriPath = "http://192.168.1.20:8080/coco/postTest";
    8. int statusCode = -1;
    9. String result;
    10. try {
    11. /**设置请求参数
    12. * 设置请求超时 20 秒
    13. * 设置等待数据超时 10 秒
    14. * */
    15. HttpParams httpParameters = new BasicHttpParams();
    16. HttpConnectionParams.setConnectionTimeout(httpParameters, 20 * 1000);
    17. HttpConnectionParams.setSoTimeout(httpParameters, 10 * 1000);
    18. /**
    19. * 设置 post 传递的数据
    20. * 为 HttpPost 设置推送的内容,使用 utf-8 编码
    21. */
    22. List<NameValuePair> params = new ArrayList<>();
    23. params.add(new BasicNameValuePair("id", "9527"));
    24. params.add(new BasicNameValuePair("name", "宁王"));
    25. params.add(new BasicNameValuePair("info", "造反啦"));
    26. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
    27. httpPost = new HttpPost(uriPath);
    28. httpPost.setEntity(entity);
    29. HttpClient httpclient = new DefaultHttpClient(httpParameters);
    30. HttpResponse httpResponse = httpclient.execute(httpPost);
    31. statusCode = httpResponse.getStatusLine().getStatusCode();
    32. if (statusCode == 200) {
    33. HttpEntity httpEntity = httpResponse.getEntity();
    34. result = EntityUtils.toString(httpEntity, "utf-8");
    35. Log.i("Wmx logs::", "服务器返回=" + result);
    36. } else {
    37. return "请求失败,错误代码:" + statusCode;
    38. }
    39. } catch (IOException e) {
    40. e.printStackTrace();
    41. return "请求失败,错误代码:" + statusCode;
    42. } finally {
    43. /**无论成功与否都要释放连接,并关闭*/
    44. if (httpPost != null && !httpPost.isAborted()) {
    45. httpPost.abort();
    46. }
    47. }
    48. return "请求成功:" + result;
    49. }
  • 此时 web 服务端后台相应的新增一个用于被 post 请求的接口:

    /**

    1. * post 请求地址:http://localhost:8080/coco/postTest
    2. */
    3. @RequestMapping(value = "postTest", method = RequestMethod.POST)
    4. public void postTest(String id, String name, String info, HttpServletResponse response) {
    5. try {
    6. System.out.println(new Date() + " 被人家访问了...id=" + id + "\tname=" + name + "\taddress=" + info);
    7. PrintWriter printWriter = response.getWriter();
    8. printWriter.write("{\"message\":\"get Test success\"}");
    9. printWriter.flush();
    10. printWriter.close();
    11. } catch (IOException e) {
    12. e.printStackTrace();
    13. }
    14. }

web 服务器端控制台输出如下:

Sun Sep 30 16:41:11 CST 2018 被人家访问了…id=9527 name=宁王 address=造反啦

Android 控制台输出如下:

I/Wmx logs::: 点我…..
I/Wmx logs::: 网络访问新线程=Thread-1512
I/Wmx logs::: 服务器返回={“message”:”get Test success”}

  • 同理还有:org.apache.http.client.methods.HttpDelete、org.apache.http.client.methods.HttpPut 都是同理,不再累述。

发表评论

表情:
评论列表 (有 0 条评论,411人围观)

还没有评论,来说两句吧...

相关阅读