HttpURLConnection

从我们在浏览器的地址栏输入http://blog.csdn.net/seu_calvin后回车,到我们看到该博客的主页,这中 间经历了什么呢?简单地回答这个问题,大概是经历了域名解析、 TCP的三次握手、建立TCP连接后发起

HTTP请求、服务器响应HTTP请求、浏览器解析html代码,同时请求html代码中的资源(如js、 css、图 片等)、最后浏览器对页面进行渲染并呈现给用户。下面分别介绍一下每个过程。

1.域名解析

以Chrome浏览器为例, Chrome会解析域名对应的IP地址。 (1) Chrome浏览器会首先搜索浏览器自身的DNS缓存(可以使用 chrome://net-internals/#dns 来进 行查看),浏览器自身的DNS缓存有效期比较短,且容纳有限,大概是1000条。如果自身的缓存中存在

blog.csdn.net 对应的IP地址并且没有过期,则解析成功。 (2)如果(1)中未找到,那么Chrome会搜索操作系统自身的DNS缓存(可以在命令行下使用 ipconfig /displaydns 查看)。如果找到且没有过期则成功。 (3)如果(2)中未找到,那么尝试读取位于C:\Windows\System32\drivers\etc下的hosts文件,如果 找到对应的IP地址则解析成功。 (4)如果(3)中未找到,浏览器首先会找TCP/IP参数中设置的本地DNS服务器,并请求LDNS服务器 来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都 很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。否则本地DNS服务器会请求 根DNS服务器。 (5)本地DNS会把请求发至13台根DNS,根DNS服务器会返回所查询域的主域名服务器的地址(.net), 本地DNS服务器使用该IP信息联系负责.net域的这台服务器。这台负责.net域的服务器收到请求后,会返 回.net域的下一级DNS服务器地址(blog.csdn.net)给本地DNS服务器。以此类推,直至找到。

2.TCP的三次握手

这个部分正好之前整理过,可以参考NetWork——关于TCP协议的三次握手和四次挥手。

3.建立TCP连接后发起HTTP请求

TCP三次握手建立连接成功后,客户端按照指定的格式开始向服务端发送HTTP请求,服务端接收请求 后,解析HTTP请求,处理完业务逻辑,最后返回一个具有标准格式的HTTP响应给客户端。

3.1 HTTP请求格式

HTTP请求格式如下所示四部分组成,分别是请求行、请求头、空行、消息体,每部分内容占一行。请求行:由三部分组成:分别是请求方法(GET/POST/DELETE/PUT/HEAD)、 URI路径、 HTTP版本 号。 请求头:缓存相关信息(Cache-Control, If-Modified-Since)、客户端身份信息(User-Agent)、是 否支持gzip压缩,等键值对信息。 空行。 主体:客户端发给服务端的请求数据,这部分数据并不是每个请求必须的。

常用的GET、 POST、 PUT、 DELETE四种请求方式中:

(1)关于GET和DELETE将要处理的资源信息直接放在了URL中。通过"?键值对>&键值对>“的形式追 加。 HTTP RFC规范中并没有规定GET请求的URL长度,只是说明如果server无法处理太长的URI,可以 通过返回414状态码。但是大多数浏览器会讲其限制在2k-8k之间。 (2)关于POST和PUT的请求参数存储在报文的主体中。每一个参数都以”--boundary值“+"属性信息"+”

空行“+"参数值"的数据结构存储。请求数据的最后以”--boundary值--“的格式结尾。

3. 2 服务器响应HTTP请求 服务器接收处理完请求后返回一个HTTP响应消息给客户端。 HTTP响应消息的格式包括:状态行、响应 头、空行、消息体。每部分内容占一行。 状态行:有HTTP协议版本号,状态码和状态说明三部分构成。 响应头:用于说明数据的一些信息,比如数据类型、内容长度等键值对。 空行。 消息体:服务端返回给客户端的HTML文本内容。或者其他格式的数据,比如:视频流、图片或者音频 数据。

4.浏览器解析html代码,并请求html代码中的资源

浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,向服务器端发 起一个HTTP请求,如果服务器端返回304状态码(告诉浏览器服务器端没有修改该资源),那么浏览器 会直接读取本地的该资源的缓存文件。否则开启新线程向服务器端去请求下载。(这个时候就用上keepalive特性了,建立一次HTTP连接,可以请求多个资源。) 最后,浏览器利用自己内部的工作机制,把请求到的静态资源和html代码进行渲染,再呈现给用户。

2 Http网络请求方法

[] []

Http的请求方法代表了客户端想对服务器进行的操作,比如: POST、 GET、 HEAD、 PUT、 DELETE、

TRACE、 OPTIONS 。 常用的不过于CRUD四个。 增: PUT;删: DELETE;改: POST;查: GET。

2.1 GET 与 POST

GET

向服务器请求数据,获取资源,在大部分网络请求中, GET方法非常常见,并且它具有幂等性。

GET请求没有请求体,对于GET请求的请求参数在URL后面加上一个"?"的后面,参数以 key=val ue

的形式。参数与参数之间使用"&"进行连接。

GET请求是通过 URL 传输参数的,所以GET请求可以传输的参数是有限的。

POST

用于向表单提交数据,传送的数据放在请求体中。 在POST请求中,请求参数放在请求体中,服务器会根据POST请求体中的参数创建一个页面,然后 返回给客户端。 POST不具有幂等性。

POST 与 GET 区别

1 . 作用不同: GET 用于获取资源,而 POST 用于传输实体主体。

2. 参数位置不一样: GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出 现在 URL 中,而 POST 的参数存储在实体主体中。但是并不是 POST 参数存储在实体主体中就认 为它的安全性更高,我们可以通过一些抓包工具如(Fiddler)查看。 在URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如 中文 会 转换为 %E4%B8%AD%E6%96%87 ,而空格会转换为 %20 。 POST 支持标准字符集。

3. 安全性:安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。 GET 方法是安全的, 而 POST 却不是,因为 POST 的目的是传送实体主体内容,这个内容可能是用户上传的表单数据, 上传成功之后,服务器可能把这个数据存储到数据库中,因此状态也就发生了改变。 安全的方法除了 GET 之外还有: HEAD、 OPTIONS。 不安全的方法除了 POST 之外还有 PUT、 DELETE。

1 . 幂等性: GET是幂等性,而POST不是幂等性。在正确实现的条件下, GET, HEAD, PUT,

OPTIONS 和 DELETE 等方法都是幂等的,而 POST 方法不是。 GET /pageX HTTP/1.1 是幂等的, 连续调用多次,客户端接收到的结果都是一样的: GET /pageX HTTP/1.1 GET /pageX HTTP/1.1 GET /pageX HTTP/1.1 GET /pageX HTTP/1.1

POST /add_row HTTP/1.1 不是幂等的,如果调用多次,就会增加多行记录: POST /add_row HTTP/1.1 -> Adds a 1nd row POST /add_row HTTP/1.1 -> Adds a 2nd row POST /add_row HTTP/1.1 -> Adds a 3rd row DELETE /idX/delete HTTP/1.1 是幂等的,即便不同的请求接收到的状态码不一样: DELETE /idX/delete HTTP/1.1 -> Returns 200 if idX exists DELETE /idX/delete HTTP/1.1 -> Returns 404 as it just got deleted DELETE /idX/delete HTTP/1.1 -> Returns 404

1 . 可缓存性: GET可以缓存,但是POST大部分情况下无法缓存。 如果要对响应进行缓存,需要满足 几个条件: 请求报文的 HTTP 方法本身是可缓存的,包括 GET 和 HEAD,但是 PUT 和 DELETE 不可缓存,

POST 在多数情况下不可缓存的。 响应报文的状态码是可缓存的,包括: 200 , 203 , 204 , 206 , 300 , 301 , 404 , 405 , 410 , 414, and 501。 响应报文的 Cache-Control 首部字段没有指定不进行缓存。

1 . 在使用 XMLHttpRequest 的 POST 方法时,浏览器会先发送 Header 再发送 Data。但并不是所有 浏览器会这么做,例如火狐就不会。而 GET 方法 Header 和 Data 会一起发送。

XMLHttpRequest 简介: XMLHttpRequest 是一个 API,它为客户端提供了在客户端和服务器之间 传输数据的功能。它提供了一个通过 URL 来获取数据的简单方式,并且不会使整个页面刷新。这 使得网页只更新一部分页面而不会打扰到用户,局部刷新避免资源浪费。并且XMLHttpRequest 在 AJAX 中被大量使用。

2.2 HEAD

获取报文首部,并且具有幂等性。 HEAD请求与GET请求一样,没有请求体。但是与GET区别在于,当使 用HEAD进行请求服务器时,服务器只返回响应头,不返回响应体。 常用于: - 检查请求的URL是否有 效,可以通过响应码进行判断 - 可以根据返回的响应头进行判断资源是否被篡改

2.3 PUT

用来向服务器上传文件,并且具有幂等性。与POST区别在于: POST用于向服务器发送数据,而PUT用 于向服务器储存数据。 它自身不带验证机制,导致任何人都可以上传文件,有很大的安全问题,一般不 使用该方法。 当使用PUT进行请求时,服务器会使用PUT的请求体的数据创建一个由它请求的URL命名 的新文件。没有进行特殊说明,一般PUT请求的请求体只用于创建或修改该资源上。如果请求的URL在 服务器中不存在,则根据该请求的主体部分创建一个由该请求URL命名的新文档;如果该URL在服务器 中已经存在,则用该主体替代他。

2.4 DELETE

用于删除服务器上的文件,并且具有幂等性。但是服务器并不是真正的删除文件,而是给需要删除的文 件做一个标记,与PUT功能相反。它也没有验证机制,有很大的安全问题。

2.5 PATCH

对资源进行部分修改。与PUT区别在于, PUT是修改所有资源,替代它,而PATCH只是修改部分资源。

2.6 OPTIONS

具有幂等性。当客户端不清楚对资源操作的方法,可以使用这个请求询问服务器该资源支持的请求方 法,在响应字段allow中返回,比如: Al l ow : GET , POST , HEAD 。它只可以在HTTP 1.1中使用。

2.7 TRACE

用来查看一个请求,经过网关,代理到达服务器,最后请求的变换。显示出请求到响应的传输路径。不 过有安全漏洞,会泄漏网站信息,被服务器禁止使用。仅在HTTP 1.1版本可以使用。

2.8 CONNECT

要求客户端与另一个远程服务器建立一个特殊的隧道,这时候web服务器充当代理角色。仅在HTTP 1.1

版本可以使用。 使用 SSL( Secu re Sockets Laye r,安全套接层) 和 TLS(Transpo rt Laye r Secu ri ty,传输层安全) 协议在网络隧道中进行加密传输。在介绍HTTP 请求方法之前,先来谈一下幂等 性,那什么是幂等性呢。

幂等性:指的是同样的请求不管执行多少次,效果都是一样,服务器状态也是一样的。具有幂等性 的请求方法没有副作用。 (统计用途除外)

Http——HttpURLConnection详解

 Android设置网络权限

AndroidManifest.xml中添加

uses-permission android : name="android . permission . INTERNET" />

.1 HttpURLConnection简介

在JDK的 java.net 包中已经提供了访问HTTP协议的基本功能的类: HttpURLConnection。

HttpURLConnection是Java的标准类,它继承自 URLConnection,可用于向指定网站发送GET请求、

POST请求。 它在URLConnection的基础上提供了如下便捷的方法:

.2 HttpURLConnection使用

使用GET方式访问HTT

 try {
            URL url = new URL(“”);
            //得到网络访问对象
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(false);
            connection.setDoInput(true);
            //设置请求方式
            connection.setRequestMethod("GET");
            //是否使用缓存
            connection.setUseCaches(true);
            // 设置此 HttpURLConnecti on 实例是否应该自动执行 HTTP 重定向
            connection.setInstanceFollowRedirects(true);
            // 设置三秒
            connection.setConnectTimeout(3000);
            //连接
            connection.connect();
            int code = connection.getResponseCode();
            //如果返回码是200表示连接成功
            if (code == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                if ((line = reader.readLine()) != null) {
                    result += line;
                }
                reader.close();
            }
            //断开连接释放资源
            connection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;

用POST方式访问HTTP

 try {
            URL url = new URL(“”);
            //得到网络访问对象
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(ture);
            connection.setDoInput(true);
            //设置请求方式
            connection.setRequestMethod("POST");
            //是否使用缓存
            connection.setUseCaches(true);
            // 设置此 HttpURLConnecti on 实例是否应该自动执行 HTTP 重定向
            connection.setInstanceFollowRedirects(true);
            // 设置三秒
            connection.setConnectTimeout(3000);
            //连接


    OutputStream out=connection.getOutputStream();
            out.write(param.getBytes());
            out.flush();

            connection.connect();
            int code = connection.getResponseCode();
            //如果返回码是200表示连接成功
            if (code == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                if ((line = reader.readLine()) != null) {
                    result += line;
                }
                reader.close();
            }
            //断开连接释放资源
            connection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;

HttpURLConnection说明

HttpURLConnection对象不能直接构造,需要通过URL类中的openConnection()方法来获得。 对HttpURLConnection对象的配置都需要在connect()方法执行之前完成,因为connect()会根据

HttpURLConnection对象的配置值生成HTTP头部信息。

HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的TCP连接,并没有实际 发送HTTP请求。 **HTTP请求实际上直到我们获取服务器响应数据(如调用getInputStream()、

getResponseCode()等方法)时才正式发送出去**。

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时 (timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。

HTTP正文的内容是通过OutputStream流写入的, 向流中写入的数据不会立即发送到网络,而是 存在于内存缓冲区中,待流关闭时,根据写入的内容生成HTTP正文。 调用getInputStream()方法时,返回一个输入流,用于从中读取服务器对于HTTP请求的返回信息

我们可以使用HttpURLConnection.connect()方法手动的发送一个HTTP请求,但是如果要获取

HTTP响应的时候,请求就会自动的发起,比如我们使用HttpURLConnection.getInputStream()方 法的时候,所以完全没有必要调用connect()方法。

HttpURLConnection长连接(Keep-Alive)

JDK8自带的HttpURLConnection,默认启用keepAlive,支持HTTP / 1.1和HTTP / 1.0持久连接, 使用后的HttpURLConnection会放入缓存中供以后的同host:port的请求重用,底层的socket在

keepAlive超时之前不会关闭。

HttpURLConnection受以下system properties控制:

http . keepAl i ve=(默认值: t rue) ,是否启用keepAlive,如果设置为false,则

HttpURLConnection不会缓存,使用完后会关闭socket连接。

http . maxConnecti ons=(默认值: 5) ,每个目标host缓存socket连接的最大数。

说明:

1 . 如果在HttpURLConnection的header中加入Connection: close,则此连接不会启用keepAlive 2. 想要启用keepAlive,程序请求完毕后,必须调用HttpURLConnection.getInputStream().close()

(表示归还长连接给缓存,以供下次同host : po rt的请求重用底层socket连接) ,而不能调用

HttpURLConnection.disconnect() (表示关闭底层socket连接,不会启用 keepAl i ve)

3. keepAliveTimeout首先从http response header中获取,如果没有取到,则默认为5秒,

sun.net.www.http.KeepAliveCache.java中有一个线程,每5秒执行一次,检查缓存的连接的空闲 时间是否超过keepAliveTimeout,如果超过则关闭连接。从KeepAliveCache中获取缓存的连接时 也会检查获取到的连接的空闲时间是否超过keepAliveTimeout,如果超过则关闭连接,并且获取 下一个连接,再执行以上检查,直达获取到空闲时间在keepAliveTimeout以内的缓存连接为此。

3.5 HttpURLConnection关闭

本身要 HttpURLConnection 是很简单的,调用 connecti on . di sconnect () 就可以了。 这里是想说明一下,是否需要关闭,应该根据实际需要来: 当 HttpURLConnection 是 "Connection: close " 模式,那么关闭 inputStream 后就会自动断开连 接。 当 HttpURLConnection 是 "Connection: Keep-Alive" 模式,那么关闭 inputStream 后,并不会断 开底层的 Socket 连接。这样的好处,是当需要连接到同一服务器地址时,可以复用该 Socket。这 时如果要求断开连接,就可以调用 connecti on . di sconnect () 了。 当然, HttpURLConnection 连接到底是不是 Keep-Alive 模式,除了 HttpURLConnection 请求设置为 Keep-Alive 外 (http 1.0中默认是关闭的, http 1.1中默认启用Keep-Alive),也需要服务器支持 KeepAlive,才可以真正建立 Keep-Alive 连接。

3.6 与HttpClient的区别

在一般情况下,如果只是需要向Web站点的某个简单页面提交请求并获取服务器响应,

HttpURLConnection完全可以胜任。但在绝大部分情况下,

Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户 登录而且具有相应的权限才可访问该页面。 在这种情况下,就需要涉及Session、 Cookie的处理了,如果打算使用HttpURLConnection来处理 这些细节,当然也是可能实现的,只是处理起来难度就大了。为了更好地处理向Web站点请求,包括处理Session、 Cookie等细节问题, Apache开源组织提供了 一个HttpClient项目,看它的名称就知道, 它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不 会缓存服务器的响应, 不能执行HTML页面中嵌入的Javascript代码;也不会对页面内容进行任何解析、处理。 简单来说, HttpClient就是一个增强版的HttpURLConnection, HttpURLConnection可以做的事情

HttpClient全部可以做;

HttpURLConnection没有提供的有些功能, HttpClient也提供了,但它只是关注于如何发送请求、 接收响应,以及管理HTTP连接。

4 JSON

Json(Javascript Object notation)作为一种轻量级的数据传输格式,在现代软件开发中广泛使用,采用完 全独立于语言的文本格式,具有可读性强、编写容易,更利于机器的解析与生成。

4.1 JSON与Xml的比较

Json与xml分别作为轻量级的数据传输格式,在软件开发中有着很重要的作用,同时两者在不同的编程 语言中能够很容易的解析与生成。根据自身的优缺点,在实际项目的开发中,选择合适的数据传输格式 尤为重要,比较如下

Json与xml具有极为丰富的解析方式

Json与xml比较, json的数据小

Json与xml比较, xml能够更好的描述对象

Json与xml比较, json的传输效率更高

Json与xml比较,在编写方面, xml具有丰富的工具编写

4.2 JSON的结构

JSON具有以下这些表现形式

对象(JSONObject):

对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个

“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。

JSONObject结构图

数组(JSONArray):

数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分 隔。

JSON的使用

1.生成JSONObject

2.解析JsonObject

生成JSONArray

JsonObject obj =new JsonObjec

解析json

              try {
                    JSONObject object=new JSONObject(result);
                    JSONArray array=object.getJSONArray("data");
                    for (int i = 0; i < array.length(); i++) {
                        JSONObject object1=array.getJSONObject(i);
                        String title=object1.getString("title");
                        String desc=object1.getString("desc");
                        String pic=object1.getString("pic");

                        News news=new News(title,desc,pic);
                        Log.i("json解析",news.toString());
                        list.add(news);
                    }

                    NewsAdapter newsAdapter=new NewsAdapter(list);
                    LinearLayoutManager layoutManager=new LinearLayoutManager(MainActivity3.this);
                    rv_show.setLayoutManager(layoutManager);
                    rv_show.setAdapter(newsAdapter);
                } catch (JSONException e) {

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值