Http编程
1.Web应用程序使用的基础协议,例如,浏览器访问网站,手机App访问后台服务器,都是通过HTTP协议实现的
2.浏览器请求访问某个网站时发送的HTTP请求-响应。首先建立TCP连接,且服务器总是使用80
端口和加密端口443
,然后,浏览器向服务器发送一个HTTP请求,服务器收到后,返回一个HTTP响应,并且在响应中包含了HTML的网页内容,这样,浏览器解析HTML后就可以给用户显示网页了
3.HTTP请求的格式是固定的 header+body
http请求:
POST /login HTTP/1.1 //请求方法 路径 HTTP版本
Host: www.example.com //请求的网站
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=hello&password=123456
http响应:
HTTP/1.1 200 OK //HTTP版本 响应代码 响应说明
Content-Type: text/html
Content-Length: 134332
<!DOCTYPE html>
<html><body>
<h1>Hello</h1>
...
- Host:表示请求的域名,因为一台服务器上可能有多个网站,因此有必要依靠Host来识别请求是发给哪个网站的;
- User-Agent:表示客户端自身标识信息,不同的浏览器有不同的标识,服务器依靠User-Agent判断客户端类型是IE还是Chrome,是Firefox还是一个Python爬虫;
- Accept:表示客户端能处理的HTTP响应格式,
*/*
表示任意格式,text/*
表示任意文本,image/png
表示PNG格式的图片; - Accept-Language:表示客户端接收的语言,多种语言按优先级排序,服务器依靠该字段给用户返回特定语言的网页版本
发送JSON的POST
请求:
POST /login HTTP/1.1
Content-Type: application/json
Content-Length: 38
{"username":"bob","password":"123456"}
4.客户端只依据响应码判断服务器返回是否成功
- 1xx:表示一个提示性响应,例如101表示将切换协议,常见于WebSocket连接;
- 2xx:表示一个成功的响应,例如200表示成功,206表示只发送了部分内容;
- 3xx:表示一个重定向的响应,例如301表示永久重定向,303表示客户端应该按指定路径重新发送请求;
- 4xx:表示一个因为客户端问题导致的错误响应,例如400表示因为Content-Type等各种原因导致的无效请求,404表示指定的路径不存在;
- 5xx:表示一个因为服务器问题导致的错误响应,例如500表示服务器内部故障,503表示服务器暂时无法响应。
5.每次发送一个HTTP请求,客户端都需要先创建一个新的TCP连接,然后,收到服务器响应后,关闭这个TCP连接。由于建立TCP连接就比较耗时,
因此,为了提高效率,HTTP/1.1协议允许在一个TCP连接中反复发送-响应,这样就能大大提高效率
HTTP协议是一个请求-响应协议,客户端在发送了一个HTTP请求后,必须等待服务器响应后,才能发送下一个请求,这样一来,如果某个响应太慢,它就会堵住后面的请求。
所以,为了进一步提速,HTTP/2.0允许客户端在没有收到响应的时候,发送多个HTTP请求,服务器返回响应的时候,不一定按顺序返回,只要双方能识别出哪个响应对应哪个请求,就可以做到并行发送和接收
6.例子,jdk11之前版本,11开始有了更新
URL url=new URL("https://www.baidu.com/"); HttpURLConnection conn= (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setUseCaches(false); conn.setConnectTimeout(5000); conn.setRequestProperty("Accept","*/*"); conn.setRequestProperty("User-Agent","xxx"); conn.connect();//连接发起请求 if(conn.getResponseCode()!=200){ System.out.println(conn.getResponseCode()); throw new RuntimeException("bat response"); } Map<String, List<String>> map=conn.getHeaderFields(); for(String key:map.keySet()){ System.out.println(key+":"+map.get(key)); } System.out.println("end!!!!");
最简单的例子,不考虑合理性,能正常发出请求,得到响应
1. //请求的网站域名 URL url=new URL("https://www.baidu.com"); 2.//通过域名建立连接,向下转型为HttpUrlconnection HttpURLConnection conn= (HttpURLConnection)url.openConnection(); 3.//请求 conn.connect();