1.HTTP协议:

  • Hyper Text Transfer Protocol:超文本传输协议
  • 基于TCP协议之上的请求/响应协议
  • 目前使用最广泛的高级协议
    * 使用浏览器浏览网页和服务器交互使用的就是HTTP协议
    * 手机应用上绝大多数程序与服务器之间交互数据使用的也是HTTP协议。
  • HTTP协议是一个纯文本协议
  • HTTP是一个请求/响应协议。浏览器发送一个请求,服务器收到以后,然后发送响应。

HTTP 1.0:

  • 每次请求都会创建一个新的HTTP连接,浏览器在请求一个网页之后,往往还是多次请求图片、CSS、JS等其他资源,而创建TCP连接需要一定的时间,所以HTTP1.0传输效率比较低

HTTP 1.1:
在HTTP1.0之上做了改进,多个HTTP请求可以通过一个TCP连接来完成。这样浏览器只需要和服务器建立一次TCP连接,就可以反复进行HTTP的请求/响应。它的效率比HTTP1.0要高

HTTP 2.0:
又对HTTP多了改进。多个HTTP请求也是通过一次TCP连接来完成的,但是浏览器在发送了一次HTTP请求以后,不需要等待响应,就可以立即发送第2个、第3个,而服务器在接收到请求的同时,又把前面已经接收的请求对应的响应发送出去,也就是说HTTP 2.0 请求/响应是可以异步发送的

2.HTTP请求格式

GET POST
请求 GET / HTTP/1.1 GET方法 路径 HTTP协议版本

Host: www.baidu.com 请求地址

User-Agent: Mozilla/5.0 (Linux; Android 9; ALP-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36

User-Agent表示浏览器本身,如火狐

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

Accept表示能接收什么样的数据

Accept-Language: zh-CN,zh;q=0.9 表示用户的语言
POST: /dataPipeline/uploadData?channel=statistics&version=v1 HTTP/1.1 请求方法 路径 HTTP协议类型

Host: cgicol.amap.com

User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; ALP-AL00 Build/HUAWEIALP-AL00)

Accept: */*

Accept-Language: zh-CN,zh,en

Content-Type: application/x-www-form-urlencoded 数据格式html表单

Content-Length: 264 数据长度264

channel=statistics&version=v1... Body具体的数据
响应 GET响应:HTTP/1.1 302 Found HTTP协议 响应

Content-Type:text/html;charset=utf-8 响应的内容是网页,编码是utf-8

Content-Length:0 响应的长度

响应体和header以空行分隔
HTTP/1.1 200

Content-Type: text/html;charset=ISO-8859-1 指定具体类型

Content-Length: 32086 大小

响应体

HTTP请求分为Header和Body2个部分,Header是必须的。Get请求只有Header没有Body,而Post请求既有Header,又有Body。Header和Body之间用一个空行分隔。
如果浏览器发送的是POST请求,那么浏览器还需要告诉服务器发送的数据格式Content-Type和数据的大小Content-Length,如application/x-www-form-urlencoded表示一个html表单,大小为264个字节。

HTTP响应也分为Header和Body2个部分,Header是必须的,第1行指出HTTP响应码。2XX正确返回,3XX重定向,4XX客户端错误,5XX服务器错误。
Header还可以包含各种属性,例如Content-Type指出Body的类型,Content-Length指出Body大小。
响应体通过一个空行与Header分隔,响应的数据可以是任意的文本或者二进制格式作为body。

HTTP Server

  • 处理HTTP请求,发送HTTP响应
  • 服务器是通过Java EE Servlet API来定义的

HTTP Client

  • 发送HTTP请求,接收HTTP响应
  • java.net.HttpURLConnection处理http的客户端

GET请求示例:

  1. URL url = new URL("http://www.exampe.com"); //获取URL对象
  2. HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //通过url对象的openConnection()获取HttpURLConnection对象
  3. int code = conn.getResponseCode(); //获取响应码
  4. try(InputStream input = conn.getInputSteam()){ //读取响应数据
  5. //读取响应数据
  6. }
  7. conn.disconnect(); //断开连接

POST请求示例:

  1. URL url = new URL("http://www.example.com/login");
  2. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  3. conn.setRequestMethod("POST"); //默认方法是get
  4. conn.setDoOutput(true); //需要发送请求的数据
  5. //指定数据的Content-Type和Content-Length
  6. byte[] postData = "loginName=test&password=123456".getBytes("UTF-8");
  7. conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
  8. conn.setRequestProperty("Content-Length",String.valueOf(postData.length));
  9. try(OutputStream output = conn.getOutputStream()){ //写入请求的数据
  10. output.write(postData);
  11. }
  12. int code = conn.getResponseCode();
  13. try(inputStream input = conn.getInputStream()){
  14. //读取响应数据
  15. }
  16. conn.disconnect();

示例

  1. package com.csj2018;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. import java.net.HttpURLConnection;
  7. import java.net.URL;
  8. import java.net.URLEncoder;
  9. import java.nio.charset.StandardCharsets;
  10. import java.util.ArrayList;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. class Response{
  15. final int code;
  16. final byte[] data;
  17. public Response(int code,byte[] data){
  18. this.code = code;
  19. this.data = data;
  20. }
  21. @Override
  22. public String toString(){
  23. StringBuilder sb = new StringBuilder(1024);
  24. sb.append("HTTP状态码").append(code).append("\n");
  25. String s = new String(data,StandardCharsets.UTF_8);
  26. if(s.length() > 100){
  27. sb.append(s.substring(0,100)).append("\n...");
  28. }else{
  29. sb.append(s);
  30. }
  31. return sb.toString(); //返回状态码和前100个字节的内容,多于100,以...代表剩余内容
  32. }
  33. }
  34. public class HttpClient {
  35. public static void main(String[] args) throws Exception{
  36. Response resp = get("http://www.douban.com");
  37. System.out.println(resp);
  38. Map<String,String> postMap = new HashMap<>();
  39. postMap.put("form_email","test");
  40. postMap.put("form_password","password");
  41. Response postResp = post("https://www.douban.com/accounts/login","application/x-www-form-urlencoded",toFormData(postMap));
  42. System.out.println(postResp);
  43. }
  44. static Response get(String theUrl){
  45. System.err.println("GET:"+theUrl);
  46. HttpURLConnection conn = null;
  47. try{
  48. URL url = new URL(theUrl); //获取URL对象
  49. conn = (HttpURLConnection) url.openConnection(); //建立连接
  50. ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream(); //获取一个ByteArrayOutputStream对象用于存放读取的内容
  51. try(InputStream input = conn.getInputStream()){//获取连接获取的内容
  52. byte[] buffer = new byte[1024];
  53. for(;;){
  54. int n = input.read(buffer);
  55. System.err.println("每次读取的大小:"+n);
  56. if(n== (-1)){
  57. break;
  58. }
  59. responseBuffer.write(buffer,0,n);//将内容写入到responseBuffer
  60. System.out.println("每次写入后responseBuffer的大小"+responseBuffer.size());
  61. }
  62. }
  63. return new Response(conn.getResponseCode(),responseBuffer.toByteArray());//返回Response对象
  64. }catch (IOException e){
  65. throw new RuntimeException(e);
  66. }finally {
  67. if(conn != null){
  68. conn.disconnect();
  69. }
  70. }
  71. }
  72. static Response post(String theUrl,String contentType,String contentData){
  73. System.err.println("POST:"+theUrl);
  74. HttpURLConnection conn = null;
  75. try{
  76. URL url = new URL(theUrl);
  77. conn = (HttpURLConnection) url.openConnection();
  78. conn.setRequestMethod("POST"); //请求方法默认get,因此设为post
  79. conn.setDoOutput(true);
  80. //添加请求属性,Content-Type, Content-Length
  81. conn.setRequestProperty("Content-Type",contentType);
  82. conn.setRequestProperty("Content_Length",String.valueOf(contentData.length()));
  83. //设置body
  84. byte[] postData = contentData.getBytes(StandardCharsets.UTF_8); //
  85. try(OutputStream output = conn.getOutputStream()){
  86. output.write(postData);
  87. }
  88. ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
  89. try(InputStream input = conn.getInputStream()){
  90. byte[] buffer = new byte[1024];
  91. for(;;){
  92. int n = input.read(buffer);
  93. if(n==(-1)){
  94. break;
  95. }
  96. responseBuffer.write(buffer,0,n);
  97. }
  98. }
  99. return new Response(conn.getResponseCode(),responseBuffer.toByteArray());
  100. }catch (IOException e){
  101. throw new RuntimeException(e);
  102. }finally {
  103. if(conn != null){
  104. conn.disconnect();
  105. }
  106. }
  107. }
  108. static String toFormData(Map<String,String> map) throws IOException{
  109. List<String> list = new ArrayList<>(map.size());
  110. for(String key:map.keySet()){
  111. list.add(key + "=" + URLEncoder.encode(map.get(key),"UTF-8"));
  112. }
  113. return String.join("&",list); //key不编码,value编码,多个参数以&连接
  114. }
  115. }

3.总结:

  • HTTP协议是一个基于TCP的请求/响应协议
  • 广泛用于浏览器、手机app与服务器的数据交互
  • Java提供了HttpURLConnection实现HTTP客户端

廖雪峰Java13网络编程-3其他-1HTTP编程的更多相关文章

  1. 廖雪峰Java13网络编程-1Socket编程-2TCP编程

    1. Socket 在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据 ...

  2. 廖雪峰Java13网络编程-3其他-2RMI远程调用

    1.RMI远程调用: Remote Method Invocation 目的:把一个接口方法暴露给远程 示例: 定义一个接口Clock,它有一个方法能够获取当前的时间,并编写一个实现类,来实现这个接口 ...

  3. 廖雪峰Java13网络编程-1Socket编程-5UDP编程

    1. UDP编程: 不需要建立连接 可以直接发送和接收数据 1.1 客户端 DatagramSocket sock = new DatagramSocket(){} sock.connect(addr ...

  4. 廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

    TCP多线程编程 一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信. 因此服务器端,当我们打开一个Socket以后,通 ...

  5. 廖雪峰Java13网络编程-1Socket编程-1网络编程概念

    1.计算机网络 1.1 什么是计算机网络? 两台或更多计算机组成的网络 同一网络内的任意2台计算机都可以直接通信 所有计算机必须遵循同一种网络协议 1.2 什么是互联网 互联网是网络的网络 互联网采用 ...

  6. 廖雪峰Java13网络编程-2Email编程-2接收Email

    1接收Email协议类型 接收Email:收件人通过MUA软件把邮件从MDA抓取到本地计算机的过程. 1.1 POP3 从MUA到MDA使用最广泛的是协议是POP3 Post Office Proto ...

  7. 廖雪峰Java13网络编程-2Email编程-1发送email

    1.邮件发送 1.1传统邮件发送: 传统的邮件是通过邮局投递,从一个邮局到另一个邮局,最终到达用户的邮箱. 1.2电子邮件发送: 与传统邮件类似,它是从用户电脑的邮件软件(如outlook)发送到邮件 ...

  8. 廖雪峰Java1-3流程控制-9break、continue

    break跳出循环 int sum=0; for(int i=1; ;i++) { sum =sum + i; if(i == 100) { break; } } System.out.println ...

  9. 廖雪峰Java1-3流程控制-6 do-while循环

    do-while循环 do-while先执行循环,再判断条件. 条件满足时继续循环:条件不满足时退出:至少循环1次 int sum =0; int n = 1; do{ sum = sum + n; ...

随机推荐

  1. jsp-提交表单乱码解决

    jsp提交表单有两种方式,一种是get,一种是post,对于两种方式都可能出现乱码,以下给出两种乱码方式的解决方案. 1.post提交解决乱码 //设置解码方式,post提交解决乱码 比较简单 req ...

  2. Spark 调优之数据倾斜

    什么是数据倾斜? Spark 的计算抽象如下 数据倾斜指的是:并行处理的数据集中,某一部分(如 Spark 或 Kafka 的一个 Partition)的数据显著多于其它部分,从而使得该部分的处理速度 ...

  3. AtCoder ABC 128D equeue

    题目链接:https://atcoder.jp/contests/abc128/tasks/abc128_d 题目大意 有一个双端队列,里面有 N 个整数,你可以进行如下4种操作: A:从队头那一个到 ...

  4. 《DSP using MATLAB》Problem 8.44

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  5. 我写的界面,在ARM上跑

    这个...其实,我对ARM了解并不多,我顶多也就算是知道ARM怎么玩,EMMC干啥,MMU干啥,还有早期的叫法,比如那个NorFlash NandFlash ,然后也就没啥了. 然后写个裸机什么的,那 ...

  6. ES6 学习 -- let const

    看过很多大佬的ES6笔记,总结一下学习后的收获,给自己当作一个笔记用用: ES3.ES5定义变量有两种方法:var 和 function ES6定义变量有var.function.let.const等 ...

  7. Future Parttern 先给你这张提货单

    Future是未来,预期的意思,Thread-permessage模式是指将任务交给其他线程来做,但是如果想知道处理的结果,就要使用Future模式,它的典型应用时执行一个需要花一些时间的方法,会立即 ...

  8. PHP算法之无重复字符的最长子串

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc&quo ...

  9. BeanPostProcessor原理学习

    <Spring源码解析>笔记 1.自定义的BeanPostProcessor @Component public class MyBeanPostProcessor implements ...

  10. 安装xampp之后报错XAMPP: Starting Apache...fail.

    1.安装完成xampp之后报错: 2.网上查到的解决办法是:输入sudo apachectl stop 之后再次启动lampp,问题得以解决: 过两天发现问题并没有解决: ①在网上查询发现是因为端口被 ...