HttpURLConnection使用

HTTP请求实战
本文介绍如何使用HttpURLConnection发起HTTP请求,并通过实例演示GET和POST请求的具体实现。文章还讲解了如何处理服务器响应,以及如何在Android应用中展示这些响应。

使用 HTTP协议访问网络

对于 HTTP协议, 你只需要稍微了解一些就足够了
它的工作原理特别的简单,就是客户端向服务器发出一条 HTTP请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行 解析和处理就可以了

一个浏览器的基本工作原理也就是如此了。比如说 上一篇文章中使用到的 WebView控件,其实也就是我们向百度的服务器发起了一条 HTTP请求, 接着服务器分析出我们想要访问的是百度的首页,于是会把该网页的 HTML代码进行返回, 然后WebView再调用手机浏览器的内核对返回的HTML代码进行解析,最终将页面展示出来

简单来说,WebView已经在后台帮我们处理好了发送 HTTP请求、接收服务响应、解析 返回数据,以及最终的页面展示这几步工作,不过由于它封装得实在是太好了,反而使得我 们不能那么直观地看出 HTTP协议到底是如何工作的。因此,接下来就让我们通过手动发送 HTTP请求的方式,来更加深入地理解一下这个过程

使用 HttpURLConnection

在 Android上发送 HTTP请求的方式一般有两种,HttpURLConnection和 HttpClient,本篇中我们先来学习一下 HttpURLConnection的用法

首先需要获取到 HttpURLConnection的实例,一般只需 new出一个 URL对象,并传入目标的网络地址,然后调用一下 openConnection()方法即可:

URL url = new URL("http://www.baidu.com"); 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 

得到了 HttpURLConnection的实例之后,我们可以设置一下 HTTP请求所使用的方法
常用的方法主要有两个,GET和 POST
GET表示希望从服务器那里获取数据,而 POST则 表示希望提交数据给服务器

connection.setRequestMethod("GET"); 

接下来就可以进行一些自由的定制了,比如设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等。这部分内容根据自己的实际情况进行编写

connection.setConnectTimeout(8000);
connection.setReadTimeout(8000); 

之后再调用 getInputStream()方法就可以获取到服务器返回的输入流了,剩下的任务就是 对输入流进行读取

InputStream in = connection.getInputStream();

最后可以调用 disconnect()方法将这个 HTTP连接关闭掉

connection.disconnect();

栗子

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"
    >

    <Button
        android:id="@+id/send_request"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send Request"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/response"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />
    </ScrollView>

</LinearLayout>

java

public class MainActivity extends Activity implements View.OnClickListener {

    public static final int SHOW_RESPONSE = 0;
    private Button button;
    private TextView textView;

    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SHOW_RESPONSE:
                    String response = (String) msg.obj;
                    textView.setText(response);
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = findViewById(R.id.send_request);
        textView = findViewById(R.id.response);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.send_request:
                sendRequestWithURLConnection();
                break;
        }
    }

    private void sendRequestWithURLConnection() {
        //开启线程发起网络请求
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                try {
                    URL url = new URL("https://www.baidu.com");
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream inputStream = connection.getInputStream();
                    //对获取的输入流进行读取
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    Message message = new Message();
                    message.what = SHOW_RESPONSE;
                    //将服务器返回的结果存放到Message中
                    message.obj = response.toString();
                    handler.sendMessage(message);
                } catch (MalformedURLException e) {

                } catch (ProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

如果要post一个json要这样写

		OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());  
		JSONObject jsonObj = new JSONObject(params);
        //发送参数  
        writer.write(jsonObj te); 
       //清理当前编辑器的左右缓冲区,并使缓冲区数据写入基础流  
        writer.flush(); 

其中params是hashmap键值对,转为json后传递

注意
1、郭大神《第一行代码》原文中new出一个 URL对象时:

URL url = new URL("http://www.baidu.com");

但我这样试过,是请求不到数据的,所以改成:

URL url = new URL("https://www.baidu.com");

2、AndroidManifest.xml中声明网络权限

效果如图:

这里写图片描述

我们在 Send Request 按钮的点击事件里调用了 sendRequestWithHttpURLConnection()方法,在这个方法中先是开启了一个子线程,然后在子线程里使用HttpURLConnection 发出一条 HTTP请求,请求的目标地址就是百度的首页

接着利用 BufferedReader对服务器 返回的流进行读取,并将结果存放到了一个 Message对象中

这里为什么要使用 Message对 象呢?当然是因为子线程中无法对 UI进行操作了。我们希望可以将服务器返回的内容显示 到界面上,所以就创建了一个 Message对象,并使用 Handler将它发送出去。之后又在 Handler 的 handleMessage()方法中对这条 Message进行处理,最终取出结果并设置到 TextView上

那么如果是想要提交数据给服务器应该怎么办呢?其实也不复杂,只需要将 HTTP请求 的方法改成 POST,并在获取输入流之前把要提交的数据写出即可。比如说我们想要向服务器提交用户名和密 码,就可以这样写

connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.writeBytes("username=admin&password=123456"); 

最后看一篇文章提升下

网络编程的最佳实践

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值