Web:全球广域网,也称为万维网(www),能够通过浏览器访问的网站
JavaWeb: 是用 Java技术来解决相关web互联网领域的技术栈。
JavaWeb 技术栈
B/S 架构:
Browser/Server,浏览器/服务器 架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可。
好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本。
静态资源:
HTML、CSS、JavaScript、图片等。负责页面展现
动态资源:
Servlet、JSP 等。负责逻辑处理
数据库:
负责存储数据
HTTP协议:
HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
特点:
基于TCP协议:面向连接,安全
基于请求-响应模型的:一次请求对应一次响应
HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
缺点:多次请求间不能共享数据。
优点:速度快
HTTP-请求数据格式
请求数据分为3部分:
请求行:请求数据的第一行。其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本;
请求头:第二行开始,格式为key:value形式;
常见的HTTP 请求头:
Host: 表示请求的主机名;
User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ... Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ...) like Gecko;
Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;
Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。
请求体:POST请求的最后一部分,存放请求参数。
GET请求和 POST请求区别:
GET请求请求参数在请求行中,没有请求体。POST请求请求参数在请求体中;
GET请求请求参数大小有限制,POST没有。
get:
GET / HTTP/1.1
Host: www.itcast.cn
Connection: keep-alive
User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
…
post:
POST / HTTP/1.1
Host: www.itcast.cn
Connection: keep-alive
Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
username=name&password=123456
HTTP-响应数据格式
响应数据分为3部分:
响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述。
状态码:
响应头:第二行开始,格式为key:value形式
常见的HTTP 响应头:
Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;
Content-Length:表示该响应内容的长度(字节数);
Content-Encoding:表示该响应压缩算法,例如gzip;
Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
响应体: 最后一部分。存放响应数据
例如:
HTTP/1.1 200 OK Server: Tengine Content-Type: text/html Transfer-Encoding: chunked… <html> <head> <title></title> </head> <body></body> </html> |
模拟接收和响应
import sun.misc.IOUtils; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.nio.file.Files; /* 自定义服务器 */ public class Server { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8080); // 监听指定端口 System.out.println("server is running..."); while (true){ Socket sock = ss.accept(); System.out.println("connected from " + sock.getRemoteSocketAddress()); Thread t = new Handler(sock); t.start(); } } } class Handler extends Thread { Socket sock; public Handler(Socket sock) { this.sock = sock; } public void run() { try (InputStream input = this.sock.getInputStream()) { try (OutputStream output = this.sock.getOutputStream()) { handle(input, output); } } catch (Exception e) { try { this.sock.close(); } catch (IOException ioe) { } System.out.println("client disconnected."); } } private void handle(InputStream input, OutputStream output) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8)); // 读取HTTP请求: boolean requestOk = false; String first = reader.readLine(); if (first.startsWith("GET / HTTP/1.")) { requestOk = true; } for (;;) { String header = reader.readLine(); if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕 break; } System.out.println(header); } System.out.println(requestOk ? "Response OK" : "Response Error"); if (!requestOk) { // 发送错误响应: writer.write("HTTP/1.0 404 Not Found\r\n"); writer.write("Content-Length: 0\r\n"); writer.write("\r\n"); writer.flush(); } else { // 发送成功响应: //读取html文件,转换为字符串 BufferedReader br = new BufferedReader(new FileReader("http/html/a.html")); StringBuilder data = new StringBuilder(); String line = null; while ((line = br.readLine()) != null){ data.append(line); } br.close(); int length = data.toString().getBytes(StandardCharsets.UTF_8).length; writer.write("HTTP/1.1 200 OK\r\n"); writer.write("Connection: keep-alive\r\n"); writer.write("Content-Type: text/html\r\n"); writer.write("Content-Length: " + length + "\r\n"); writer.write("\r\n"); // 空行标识Header和Body的分隔 writer.write(data.toString()); writer.flush(); } } } |
Web服务器:
封装了很多HTTP的操作:负责解析 HTTP 协议,解析请求数据,并发送响应数据。
看 开源工具专栏/tomcat
servlet
看本专栏的详述