第三部分:Java后端开发

第9章:Java Web基础

9.1 HTTP协议

1. 核心概念:什么是HTTP?

HTTP (HyperText Transfer Protocol, 超文本传输协议) 是万维网(World Wide Web)的通用语言。它是一套详细的规则,规定了你的浏览器(客户端)和网站服务器之间应该如何对话、如何请求信息、如何回应信息。

好比说:HTTP就像一套国际通用的“图书馆借书的标准流程和表格”。无论你去哪个国家的图书馆(网站服务器),只要你按照这套标准填表(发送HTTP请求),图书管理员(服务器)就能看懂并为你服务。

2. 对话流程:请求-响应模型

HTTP的核心就是一个简单的“一问一答”模型。

  • 第一步:请求 (Request) 你的浏览器(比如Chrome)会向服务器发送一个“请求报文”。

    • 好比说:你填写一张“借书申请单”,递给图书管理员。

  • 第二步:响应 (Response) 服务器收到请求并处理后,会向你的浏览器发回一个“响应报文”。

    • 好比说:图书管理员根据你的申请单,找到书后连同一张“处理回执”一起递给你。

3. “请求”里写了什么?

一张HTTP请求单主要包含三部分。

  • 请求行 (Request Line): 最重要的一行,说明了“你想做什么”和“你想要什么”。

    • GET /courses/java-basics.html HTTP/1.1

    • GET: 这是请求方法 (Method)GET是最常见的方法,意思是“请给我这个资源”。另一个常见的是POST,意思是“我要提交这些数据给你”(比如提交一个登录表单)。

    • /courses/java-basics.html: 这是请求的资源路径 (URL),告诉服务器你想要哪个文件或页面。

    • HTTP/1.1: 这是协议的版本号。

  • 请求头 (Headers): 提供一些附加信息。

    • Host: www.example.com (我想访问的是哪个网站)

    • User-Agent: Chrome/115.0 (我用的是什么浏览器)

  • 请求体 (Body): 只有在使用POST等方法提交数据时才有。

    • 好比说:你填写的登录表单里的用户名和密码就放在这里。

4. “响应”里又有什么?

服务器的回执也包含三部分。

  • 状态行 (Status Line): 包含了最重要的处理结果。

    • HTTP/1.1 200 OK

    • 200 OK: 这是状态码 (Status Code),是一个三位数代码,告诉浏览器请求的结果如何。作为小白,你必须知道这几个:

      • 200 OK: 成功。一切顺利,你请求的东西就在下面。

      • 404 Not Found: 未找到。服务器找不到你想要的资源(最常见的错误)。

      • 500 Internal Server Error: 服务器内部错误。不是你的错,是服务器自己出问题了。

      • 301 Moved Permanently: 永久重定向。你要的东西搬家了,这是新地址。

  • 响应头 (Headers): 附加信息。

    • Content-Type: text/html (我给你的是一个HTML网页)

    • Content-Length: 1024 (这个网页内容有1024字节长)

  • 响应体 (Body): 真正的网页内容(HTML代码)、图片数据等。


9.2 Web服务器 (Tomcat)

1. 核心概念:什么是Web服务器?

Web服务器是一个安装在服务器电脑上的软件,它的主要工作就是7x24小时不间断地监听网络上的HTTP请求,然后根据请求,返回相应的HTTP响应。

2. 为什么需要特殊的Tomcat?

  • 像Nginx、Apache这样的传统Web服务器,它们非常擅长处理静态资源

    • 好比说:它们是“图书管理员”,你向它要一个现成的HTML文件、一张图片,它能飞快地从书架上找到并递给你。

  • 但是,我们的Java代码不是“现成的书”,而是一套“动态生成内容的菜谱”。图书管理员看不懂菜谱,也不会做菜。

  • Tomcat 就是一个特殊的Web服务器,它不仅能当“图书管理员”,内部还集成了一个“厨房”和一位“大厨”(JVM)。这个大厨懂得如何运行Java代码(菜谱),动态地生成内容(做菜),然后再把做好的菜(生成的HTML页面)交给用户。

  • 这种能运行Java Web应用的服务器,有一个专门的名字,叫做 Servlet容器 (Servlet Container)。Tomcat是其中最著名、应用最广泛的一个。

3. 一步一步在Linux上安装和运行Tomcat

第一步:下载Tomcat 我们将使用wget命令从官网下载(请注意,版本号可能会变化,你可以去官网查看最新版)。

Bash

# 下载Tomcat 9的一个版本
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.94/bin/apache-tomcat-9.0.94.tar.gz

第二步:解压文件 下载下来的是一个压缩包,我们需要用tar命令解压它。

Bash

tar -xzvf apache-tomcat-9.0.94.tar.gz

解压后,你会得到一个名为 apache-tomcat-9.0.94 的目录。

第三步:进入bin目录并启动 Tomcat的所有可执行脚本都在bin目录里。

Bash

# 进入Tomcat的bin目录
cd apache-tomcat-9.0.94/bin/

# 执行启动脚本
./startup.sh

看到类似 "Tomcat started." 的消息就代表启动成功了。

第四步:在浏览器中验证 打开你电脑上的浏览器,访问地址: http://localhost:8080 (如果你的Linux是远程服务器,请用服务器IP地址)。如果你能看到Tomcat的欢迎页面(一只猫),那就说明你的“厨房”已经开始营业了!

第五步:关闭服务器 同样在bin目录下,执行关闭脚本。

Bash

./shutdown.sh

9.3 Servlet 技术

1. 核心概念

Servlet 就是我们之前比喻的**“能动态生成内容的Java菜谱”**。它是一个遵循特定规范的Java类,运行在Tomcat(厨房)中,专门用来接收HTTP请求、处理业务逻辑,并生成HTTP响应。

2. Servlet的生命周期(它的一生) 一个Servlet对象从被创建到被销毁,会经历几个关键阶段:

  1. init() - 初始化: 当第一个请求访问这个Servlet时,Tomcat会创建它的实例,并调用一次init()方法。好比大厨第一次看这个菜谱,会先把需要的锅碗瓢盆准备好。

  2. service() - 服务: 这是最核心的阶段。之后每一次请求访问这个Servlet,Tomcat都会调用它的service()方法。service()方法会判断请求是GET还是POST,然后分别调用doGet()doPost()方法。好比大厨根据每一份订单,反复地按照菜谱做菜。

  3. destroy() - 销毁: 当Web应用被关闭或重载时,Tomcat会调用一次destroy()方法,用于释放资源。好比厨房关门前,大厨把所有工具清洗归位。

3. 一步一步编写一个“你好,世界”的Servlet

第一步:编写Java代码 你需要创建一个Java类,让它继承javax.servlet.http.HttpServlet

Java

import javax.servlet.http.*;
import java.io.IOException;

// 我们的Servlet类,必须继承HttpServlet
public class HelloServlet extends HttpServlet {
    
    // 我们重写doGet方法来处理GET请求
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // request对象封装了所有请求信息(比如URL、参数)
        // response对象用来向浏览器发送响应
        
        // 设置响应的内容类型为HTML
        response.setContentType("text/html;charset=UTF-8");
        
        // 获取一个用于向浏览器写东西的“笔”
        PrintWriter out = response.getWriter();
        
        // 用这支笔写出HTML内容
        out.println("<html>");
        out.println("<body>");
        out.println("<h1>你好, Servlet!</h1>");
        out.println("<p>现在的时间是: " + new java.util.Date() + "</p>");
        out.println("</body>");
        out.println("</html>");
    }
}

第二步:配置web.xml(“菜谱”的注册表) 光写好菜谱还不行,你得告诉“厨房总管”Tomcat,当客人点什么“菜名”(URL)的时候,要用这份菜谱。这个注册表就是web.xml文件。

XML

<web-app>
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
  • 这段配置的意思是:将URL访问路径/hello映射到我们写的HelloServlet这个类。

第三步:部署和测试 你需要将编译好的.class文件和web.xml按照特定的目录结构放到Tomcat的webapps目录下,然后启动Tomcat。在浏览器访问 http://localhost:8080/你的应用名/hello,就能看到Servlet动态生成的页面了。


9.4 JSP 技术

1. 核心概念:为什么需要JSP?

在上面的Servlet例子中,你会发现用out.println()来一句一句地输出HTML代码,非常痛苦和低效。如果页面很复杂,代码会变得无法维护。

JSP (JavaServer Pages) 就是为了解决这个问题而生的。它允许你反过来,在一个正常的HTML文件中,嵌入Java代码。

好比说

  • Servlet: 是一个Java程序,它碰巧能生成HTML。

  • JSP: 是一个HTML页面,它碰巧能执行一些Java代码。

2. JSP是如何工作的? 这是一个非常重要的知识点:JSP的本质就是Servlet。当你第一次访问一个.jsp文件时,Tomcat会在后台偷偷地做三件事:

  1. 翻译: 将这个.jsp文件翻译成一个.java的Servlet源文件。

  2. 编译: 将这个.java文件编译成一个.class字节码文件。

  3. 执行: 像执行普通Servlet一样,执行这个编译好的类。 之后的访问,就会直接执行这个编译好的类,所以效率很高。

3. 一步一步编写一个JSP页面

第一步:创建一个.jsp文件 在你的Web应用根目录下,创建一个名为 welcome.jsp 的文件。

第二步:编写JSP代码 你可以像写普通HTML一样,然后在需要动态内容的地方插入Java代码。

HTML

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>欢迎页面</title>
</head>
<body>
    <h1>欢迎, 访客!</h1>
    
    <p>这是一个由JSP动态生成的页面。</p>

    <%-- 这是JSP注释,不会发送到浏览器 --%>

    <%-- 使用JSP表达式,直接输出Java代码的结果 --%>
    <p>服务器当前时间是: <%= new java.util.Date() %></p>

    <%-- 使用JSP脚本段,可以写更复杂的Java逻辑 --%>
    <%
        int a = 10;
        int b = 20;
        int sum = a + b;
    %>
    <p>计算结果: 10 + 20 = <%= sum %></p>

</body>
</html>
  • JSP表达式 <%= ... %>: 用于将一个Java表达式的结果直接输出到HTML中。

  • JSP脚本段 <% ... %>: 用于嵌入任意的Java代码块。

第三步:部署和测试welcome.jsp文件放到你的应用目录下,启动Tomcat,然后在浏览器访问 http://localhost:8080/你的应用名/welcome.jsp


9.5 Filter 与 Listener

1. Filter (过滤器)

  • 核心概念: Filter 就像是Servlet的“安检门”或“保安”。它位于浏览器和目标Servlet之间,可以对**进来(Request)出去(Response)**的所有数据进行拦截和处理。

  • 主要用途:

    • 统一编码: 解决全站的中文乱码问题。

    • 权限检查: 判断用户是否登录,如果未登录,则直接跳转到登录页面,不让其访问目标Servlet。

    • 日志记录: 记录所有请求的访问日志。

  • 工作流程: 一个请求可以经过多个Filter,形成一个“过滤器链”。

2. Listener (监听器)

  • 核心概念: Listener 就像一个安装在Web应用内部的“事件报警器”。它不去拦截请求,而是默默地监听某些特定事件的发生,并在事件发生时自动执行一段代码。

  • 主要监听的事件:

    • ServletContext事件: Web应用启动关闭时。

    • HttpSession事件: 一个用户会话开始结束时。

    • ServletRequest事件: 一次请求到达结束时。

  • 主要用途:

    • 应用启动时初始化资源: 比如在应用一启动时就创建好数据库连接池。

    • 统计在线人数: 通过监听Session的创建和销毁,来实时统计当前有多少用户在线。


9.6 Cookie 与 Session

1. 核心问题:如何“记住”用户?

HTTP协议本身是无状态的 (Stateless)。这意味着服务器默认是“健忘”的,它处理完你的请求后,就完全忘记你是谁了。你下一次再来,对它来说你又是一个全新的陌生人。

那么,网站(比如淘宝)是如何做到“记住你已经登录了”或者“记住你的购物车里有什么”呢?答案就是 Cookie 和 Session。

2. Cookie (客户端的“身份证”)

  • 是什么? Cookie是服务器发送给浏览器的一小段文本信息,浏览器会把它保存在你的电脑上。之后,每次你再访问这个网站时,浏览器都会自动地把这个Cookie信息再带上,发送给服务器。

  • 好比说:你去一个游乐园,检票员(服务器)在你手腕上盖了一个印章(Cookie)。之后你玩每个项目时,工作人员只要看一下你的印章,就知道你是已经买过票的游客了,无需你每次都出示门票。

3. Session (服务器的“储物柜”)

  • 是什么? Cookie虽然能识别用户,但它保存在用户电脑上,不安全(可能被篡改),而且能存储的信息量很小。所以,敏感和重要的数据应该存放在服务器端,这就是 Session

  • 工作流程:

    1. 当一个用户第一次访问网站时,服务器会为这个用户创建一个唯一的Session对象(可以把它想象成一个专属的“储物柜”),并生成一个独一无二的Session ID(储物柜的“钥匙牌号码”)。

    2. 服务器将这个Session ID通过Cookie发送给用户的浏览器。

    3. 之后,浏览器每次访问,都会自动带上这个存有Session ID的Cookie。

    4. 服务器拿到这个Session ID,就能在自己这边数以万计的“储物柜”中,准确地找到专属于这个用户的那个,然后存取里面的数据(比如登录状态、购物车信息)。

  • 好比说:Cookie只是你手腕上那个写着“柜子编号:A123”的手牌。你所有的贵重物品(Session数据)都存放在游乐园前台那个编号为A123的柜子里,而不是带在你自己身上。这样既安全又方便。

4. 一步一步在Servlet中使用Session

第一步:获取Session对象 在Servlet的doGetdoPost方法中,从request对象获取。

Java

// 如果当前用户已有Session,则获取;如果没有,则创建一个新的
HttpSession session = request.getSession();

第二步:向Session中存入数据

Java

// 将用户的登录名存入他专属的“储物柜”
session.setAttribute("loggedInUser", "Alice");

第三步:从Session中读取数据

Java

// 在另一个Servlet或下一次请求中,获取这个用户的“储物柜”
HttpSession session = request.getSession();
// 从“储物柜”中取出之前存的东西
String username = (String) session.getAttribute("loggedInUser");

if (username != null) {
    // 用户已登录
    out.println("欢迎回来, " + username);
} else {
    // 用户未登录
    out.println("请先登录。");
}

第四步:销毁Session 通常在用户点击“退出登录”时执行。

Java

session.invalidate(); // 销毁Session,清空“储物柜”

来源

更多推荐