三天急速通关JavaWeb基础知识:Day 1 后端基础知识

三天急速通关JavaWeb基础知识:Day 1 后端基础知识

  • 0 文章说明
  • 1 Http
    • 1.1 介绍
    • 1.2 通信过程
    • 1.3 报文 Message
      • 1.3.1 请求报文 Request Message
      • 1.3.2 响应报文 Response Message
  • 2 XML
    • 2.1 介绍
    • 2.2 利用Java解析XML
  • 3 Tomcat
    • 3.1 介绍
    • 3.2 Tomcat的安装与配置
    • 3.3 Tomcat的项目目录介绍
    • 3.4 Tomcat的JavaWeb项目的标准结构
    • 3.5 部署Web项目的三种方式
    • 3.5 Tomcat关联IDEA
  • 4 Servlet
    • 4.1 介绍
    • 4.2 Servelet的生命周期
    • 4.2 Servelet的继承结构
    • 4.3 自定义Servelet
    • 4.4 ServletConfig
    • 4.5 ServletContext
    • 4.6 HttpServletRequest
    • 4.6 HttpServletResponse
    • 4.7 请求转发
    • 4.8 响应重定向
  • 5 Cookie 和Session
    • 5.1 Cookie
    • 5.2 Session
  • 6 Filter
    • 6.1 介绍
    • 6.2 Filter生命周期
    • 6.3 Tomcat对Filter接口的实现
  • 7 Listener
    • 6.1 介绍
    • 6.2 监听器分类
    • 6.3 监听器实现原理

0 文章说明

学习完Java基础知识,有一定前端基础,三天急速通关尚硅谷的JavaWeb教程,整理知识体系框架,并用Kimi,DeepSeek,Copliot辅助学习,第一天整理后端相关概念。本文所提供的信息和内容仅供参考,作者和发布者不保证其准确性和完整性。

1 Http

1.1 介绍

超文本传输协议(HyperText Transfer ProtocolHTTP)是一个于应用层面向对象的协议,详细规定了浏览器和万维网服务器之间的通信规则,下面是不同Http版本的对比。

版本号发布时间主要特点支持的连接方式典型应用场景
HTTP/0.91991年最简单的请求/响应模型,仅支持GET方法简单的请求/响应静态网页浏览
HTTP/1.01996年引入了请求方法的扩展,如POSTHEAD每次请求建立新连接动态网页、表单提交
HTTP/1.11997年支持持久连接、管道化请求、内容编码等持久连接、管道化复杂网页、多媒体内容
HTTP/22015年二进制分帧、头部压缩、多路复用等多路复用、头部压缩高性能网页、移动应用
HTTP/32020年基于QUIC协议,进一步优化性能QUIC协议、更低延迟实时通信、游戏、视频流

1.2 通信过程

客户端和服务器之间的通信:客户端建立连接,通过TCP/IP协议与服务器建立连接。默认情况下,HTTP使用端口80,HTTPS使用端口443。客户端发送请求,发送Http请求报文,服务器响应请求,处理完客户端发来的请求报文之后生成响应报文发送给客户端,服务器关闭连接HTTP/1.0,每次请求/响应完成后,连接会自动关闭,HTTP/1.1,支持持久连接(Keep-Alive),可以在多个请求/响应之间复用同一个连接。

1.3 报文 Message

HTTP报文是HTTP协议中用于客户端和服务器之间通信的数据格式,一般分为:报文首部,空行,报文主体三个部分,其中报文首部分为报文行和报文头。

1.3.1 请求报文 Request Message

HTTP的请求报文一般分为:请求行,请求头,空行,请求体:

部分内容示例
请求行请求方法、请求的URLHTTP版本GET /index.html HTTP/1.1
请求头包含一些元数据,用于描述请求的附加信息Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
空行请求头和请求体之间的一个空行,表示请求头的结束CR回车符 + LR换行符
请求体(有些请求,如POST才有)包含要发送给服务器的数据,如表单数据、文件内容等name=John&age=30

1.3.2 响应报文 Response Message

HTTP的响应报文一般分为:响应行,响应头,空行,响应体:

部分内容示例
响应行HTTP版本、状态码和状态消息HTTP/1.1 200 OK
响应头描述响应的元数据Content-Type: text/html
Content-Length: 1234
空行响应头和响应体之间的分隔CR回车符 + LR换行符
响应体服务器返回的数据<html><body><h1>Hello, World!</h1></body></html>

2 XML

2.1 介绍

可扩展标记语言(eXtensible Markup LanguageXML),是一种用于标记电子文档的简单、灵活的文本格式,广泛应用于数据交换、配置文件、文档存储等领域。后续的学习中一般用作配置文件。

  • 示例
    <?xml version="1.0" encoding="UTF-8"?>
    <library><book id="1"><title>XML for Beginners</title><author>John Doe</author><year>2022</year><price>29.99</price></book>
    </library>
    
  • 其他类型的配置文件
类型扩展名格式示例说明
INI.ini键值对[section1]
key1=value1
key2=value2
键值对格式,常用于Windows应用程序的配置文件。
JSON.jsonJSON对象{
"key1": "value1",
"key2": "value2"
}
轻量级的数据交换格式,易于阅读和编写,也易于机器解析和生成。
XML.xmlXML元素<root>
<element1>value1</element1>
<element2>value2</element2>
</root>
结构化数据,常用于配置文件和数据交换。
YAML.yaml键值对key1: value1
key2: value2
人类可读的数据序列化格式,常用于配置文件和数据交换,SpringBoot
properties.properties键值对key1=value1
key2=value2
键值对格式,常用于Java应用程序的配置文件。

2.2 利用Java解析XML

Java中目前有以下几种方式解析XML

方式简要介绍适用场景
DOM解析将整个XML文档加载到内存中,形成一个树状的文档对象模型,便于随机访问和修改。适合小型XML文件,需要随机访问和修改的场景。
SAX解析事件驱动的解析方式,逐行读取XML文件。适合大型XML文件,内存占用小,逐行处理的场景。
JAXBXML文档映射到Java对象。适合将XML映射到Java对象,便于操作和处理的场景。
StAX基于流的解析方式,逐个读取XML文档的事件。适合处理大型XML文件,基于流的解析方式。
DOM4J结合了DOMSAX的优点,便于操作和处理XML文档。适合需要结合DOMSAX优点的场景,便于操作和处理XML文档。

利用DOM4J解析XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<library><book id="1"><title>XML for Beginners</title><author>John Doe</author><year>2022</year><price>29.99</price></book><book id="2"><title>Advanced XML Techniques</title><author>Jane Smith</author><year>2023</year><price>39.99</price></book>
</library>
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.util.List;public class DOM4JExample {public static void main(String[] args) {try {// 创建SAXReader对象SAXReader reader = new SAXReader();// 读取XML文件Document document = reader.read("example.xml");// 获取根元素Element root = document.getRootElement();// 遍历所有book元素for (Element book : (List<Element>) root.elements("book")) {// 获取book元素的属性String id = book.attributeValue("id");// 获取book元素的子元素String title = book.elementText("title");String author = book.elementText("author");String year = book.elementText("year");String price = book.elementText("price");// 打印信息System.out.println("Book ID: " + id);System.out.println("Title: " + title);System.out.println("Author: " + author);System.out.println("Year: " + year);System.out.println("Price: " + price);System.out.println();}} catch (DocumentException e) {e.printStackTrace();}}
}

3 Tomcat

3.1 介绍

  • Apache Tomcat 是一个开源的Java Servlet容器,提供了运行Java Web应用程序所需的环境。也可以作为独立的Web服务器使用,支持HTTP/1.1HTTP/2WebSocket等多种协议。
  • Tomcat的定位:客户端的硬件机器上运行着操作系统(如Windows),其中的应用程序(如浏览器)发送请求给服务端,服务端的硬件机器上运行的操作系统(如Linux),其中的服务器软件(如Tomcat)运行的各种App处理请求并响应。

3.2 Tomcat的安装与配置

  • 下载Tomcat10.1.x的64位Windows版(JDK1.8得切换到更高版本,我用的JDK17Tomcat10.1.34
  • 检查好JAVA_HOME环境变量
  • 启动bin/startup.bat
  • 访问http://localhost:8080/

3.3 Tomcat的项目目录介绍

  • bin 目录:包含启动和停止Tomcat的脚本文件。
    • startup.shstartup.bat:启动Tomcat的脚本。
    • shutdown.shshutdown.bat:停止Tomcat的脚本。
    • catalina.shcatalina.bat:Tomcat的核心启动脚本,其他脚本通常会调用这个脚本。
  • conf 目录:包含Tomcat的配置文件。
    • server.xml:Tomcat的主要配置文件,定义了服务器的全局设置,如端口号、连接器、服务等。
    • web.xml:定义了Web应用程序的全局设置,如Servlet映射、过滤器等。
    • context.xml:定义了上下文的配置,如资源链接、初始化参数等。
    • logging.properties:定义了日志记录的配置。
  • lib 目录:包含Tomcat运行所需的JAR文件。
    • 各种支持Tomcat运行的库文件,如catalina.jarservlet-api.jar等。
  • logs 目录:包含Tomcat运行时生成的日志文件。
    • catalina.out:Tomcat的标准输出和标准错误日志。
    • localhost.[date].log:每个Web应用程序的日志文件。
    • manager.[date].loghost-manager.[date].log:管理器和主机管理器的日志文件。
  • webapps 目录:包含部署的Web应用程序。
    每个Web应用程序都有一个独立的目录。
  • work 目录:包含Tomcat编译后的JSP文件和临时文件。
    • 编译后的JSP文件和临时文件,通常在Tomcat启动时自动生成。
  • temp 目录:包含Tomcat运行时的临时文件。
    • 各种临时文件,通常在Tomcat停止时被清理。

3.4 Tomcat的JavaWeb项目的标准结构

  • app:本应用根目录
    • static:非必要目录,存放静态资源(css, js, img)
    • WEB-INF:必要目录,受保护的资源目录,不可通过URL直接访问
      • classes:必要目录,存放编译后的Java源码和配置文件
      • lib:必要目录,存放项目依赖的JAR文件
      • web.xml:必要文件,Web项目的基本配置文件
    • index.html:非必要文件,作为默认欢迎页

3.5 部署Web项目的三种方式

  • 直接将编译好的项目放到webapps目录下
  • war包放到webapps目录下
  • tomcatconf下创建Catalina/localhost/创建一个app.xml
    <!--path: 项目的访问路径,也是项目的上下文路径,就是在浏览器中,输入的项目名称    docBase: 项目在磁盘中的实际路径 
    --> 
    <Context path="/app" docBase="D:/mywebapps/app" />
    

3.5 Tomcat关联IDEA

  • 关联IDEA
    需要IntelliJ IDEA Ultimate版本,社区版不支持直接应用服务器
    File -> Settings -> Build, Execution, Deployment -> Application Servers ->点击 + 按钮,选择 Tomcat Server -> 指定 Tomcat 的安装路径。
  • 创建Web工程
    创建Empty Project -> 添加模块 -> 右键模块,选择Open Module Settings -> 点击Project SettingsModules -> 右键刚刚创建的模块 -> 选择 Add,再选择Web-> 替换index.jspindex.html
  • 部署运行
    点击同创建Web工程Project SettingsArtifacts,检查发布结构是为Web项目,即模块名war exploded -> 点击运行按钮的下三角符号,在下拉框中选择Edit Configurations -> 添加TomcatLocal -> 右侧界面点击Deployment -> 添加Artifacts -> 确定并回到主界面点击运行。
    在这里插入图片描述
  • 资源路径和Jar包路径的设置
    注意新版没有Add as Dependency选项,得进入到模块管理手动添加。
    在这里插入图片描述

4 Servlet

4.1 介绍

ServletServe Applet) 是一种运行在服务器端的 Java 程序。在Web应用中,Servlet主要负接收、处理请求、协同调度功能以及响应数据,即控制器Controller,是Java中专门设计的一套接口来处理客户端请求。

  • 通过pom.xml配置路径映射:
    继承HttpServlet类并重写service方法(参数是带Http前缀的),在pom.xml配置请求的映射路径之后就能访问。
    package com.cut.basic;import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;/*** description: Servlet基本逻辑* author: tang* package: com.cut.basic* 2025/1/28 11:41*/
    public class ServletBasicDemo extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String flag = req.getParameter("pleaseCallMe");resp.getWriter().print("<h1>" + flag + "</h1>");}
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"version="6.0"><servlet><servlet-name>servletBasicDemo</servlet-name><servlet-class>com.cut.basic.ServletBasicDemo</servlet-class></servlet><servlet-mapping><servlet-name>servletBasicDemo</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
    </web-app>
    
    在这里插入图片描述
  • 通过Servlet@WebServlet注解配置路径映射:
    注意这里如果ServletXML同名的话会被覆盖,同时,这里的InitParams属于这个Servlet而不是req。注解的具体用法看源码即可,自己写一遍就会了。
    package com.cut.basic;import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebInitParam;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;/*** description: Servlet基本逻辑* author: tang* package: com.cut.basic* 2025/1/28 11:41*/
    @WebServlet(name = "servletBasicDemo",urlPatterns = {"/hello_annotation"},initParams = {@WebInitParam(name = "initParams", value = "It belongs to servelet, not req")}
    )
    public class ServletBasicDemo extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String flag = getServletConfig().getInitParameter("initParams");resp.getWriter().print("<h1>" + flag + "</h1>");}
    }
    
    在这里插入图片描述

4.2 Servelet的生命周期

生命周期就是对象在容器中从开始到销毁的过程,Servlet对象是Servlet容器创建的,生命周期方法是由容器(目前是Tomcat)调用。

阶段方法描述
加载和实例化-Servlet容器加载Servlet类并创建其实例。默认情况下,第一次请求时创建实例,可通过loadOnStartup配置在服务器启动时创建。
初始化init()容器调用init()方法初始化Servlet,执行一次,用于加载配置文件、创建连接等初始化工作。
请求处理service()每次请求时,容器调用service()方法处理请求,根据请求类型调用doGet()doPost()等方法。
服务终止destroy()容器关闭或释放资源时,调用destroy()方法清理资源,如关闭数据库连接等。
package com.cut.basic;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;/*** description: Servlet容器声明周期自动调用时机测试* author: tang* package: com.cut.basic* 2025/1/28 11:41*/
@WebServlet(name = "servletLifeCycleDemo",urlPatterns = {"/hello"},// 配置的是正整数则表示容器在启动时就要实例化Servlet, 数字表示的是 实例化的顺序loadOnStartup = 6
)
public class ServletLifeCycleDemo extends HttpServlet {public static int time = 0;public ServletLifeCycleDemo() {System.out.printf("time: %d\tconstructor method\n".formatted(time++));}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.printf("time: %d\tservice method\n".formatted(time++));}@Overridepublic void destroy() {System.out.printf("time: %d\tdestroy method\n".formatted(time++));}@Overridepublic void init() throws ServletException {System.out.printf("time: %d\tinit method\n".formatted(time++));}
}
  • 注意事项:
    Servlet对象是单例;每个请求都会在容器中开启一个线程,所以除了特殊目的,不要像上面的代码一样定义个timeloadOnStartup的数字1-5被容器占用,尽量不要占用。

4.2 Servelet的继承结构

  • Servlet 规范接口,所有的Servlet必须实现

    • void init(ServletConfig config) throws ServletException;
      • 初始化方法,容器在构造Servlet对象后自动调用,容器实例化一个ServletConfig对象,并在调用该方法时传入,ServletConfig对象可以为Servlet提供初始化参数。
    • ServletConfig getServletConfig();
      • 获取ServletConfig对象,可以通过该对象获取Servlet初始化参数。
    • void service(ServletRequest req, ServletResponse res);
      • 处理请求并做出响应的服务方法,每次请求产生时由容器调用。
      • 容器创建一个ServletRequest对象和ServletResponse对象,容器在调用service方法时,传入这两个对象。
    • String getServletInfo();
      • 获取ServletInfo信息的方法。
    • void destroy();
      • Servlet实例在销毁之前调用的方法。
  • GenericServlet抽象类对Servlet接口一些固定功能的粗糙实现,以及对service方法的再次抽象声明,并定义了一些其他相关功能方法。

    方法签名描述
    transient ServletConfig config;初始化配置对象作为属性。
    GenericServlet()构造器
    void destroy()销毁方法的平庸实现。
    String getInitParameter(String name)获取初始参数。
    Enumeration getInitParameterNames()返回所有初始化参数名。
    ServletConfig getServletConfig()获取初始Servlet初始配置对象ServletConfig。
    ServletContext getServletContext()获取上下文对象ServletContext。
    String getServletInfo()获取Servlet信息的平庸实现。
    void init(ServletConfig config) 初始化方法的实现,并在此调用了init的重载方法。
    void init() 重载init方法,为了让我们自己定义初始化功能的方法。
    void log(String msg)打印日志的方法。
    void log(String message, Throwable t)打印日志的方法及重载。
    abstract void service(ServletRequest req, ServletResponse res) 服务方法。
    String getServletName()获取ServletName的方法。
  • HttpServlet抽象类继承GenericServlet,除了基本的实现以外,增加了更多的基础功能。

    方法签名描述
    HttpServlet()构造器,用于处理继承。
    void service(ServletRequest req, ServletResponse res)对服务方法的实现。在该方法中,将请求和响应对象转换成对应HTTP协议的HttpServletRequest和HttpServletResponse对象,并调用重载的service方法。
    void service(HttpServletRequest req, HttpServletResponse res)重载的service方法,被重写的service方法所调用。在该方法中,通过请求方式判断,调用具体的do***方法完成请求的处理。
    void doGet(HttpServletRequest req, HttpServletResponse resp)对应GET请求的处理方法,DO系列省略。

4.3 自定义Servelet

来源于尚硅谷教程两种自定义的方式截图,非常清晰。
在这里插入图片描述

4.4 ServletConfig

ServletConfigJava Servlet API 中的一个接口,它代表一个 Servlet 的配置信息。该接口定义了获取 Servlet 初始化参数和 Servlet上下文的方法。

package jakarta.servlet;import java.util.Enumeration;public interface ServletConfig {// 获取Servlet名称String getServletName();// 获取Servlet上下文,ServletContext getServletContext();// 获取初始化参数String getInitParameter(String var1);// 获取所有初始化参数名Enumeration<String> getInitParameterNames();
}

4.5 ServletContext

ServletContextJava Servlet API 中的一个接口,代表了 Servlet 的上下文环境。它提供了一种机制,使得运行在同一个 Web 应用程序中的不同 Servlet 之间可以共享数据和资源。
简而言之,这个Servlet需要用到另一个Servlet的时候需要用ServletContext传话。

  • ServletContext接口内置几十个方法,下面列举一些常见方法

    • 获取初始参数
    方法名描述
    String getInitParameter(String name)获取指定名称的上下文初始化参数的值。
    Enumeration<String> getInitParameterNames()获取所有上下文初始化参数的名称。
    • 获取资源的磁盘路径:假设Web应用部署在Tomcatwebapps目录下,应用名为myapp,那么/WEB-INF/config.xml的实际路径可能是:/path/to/tomcat/webapps/myapp/WEB-INF/config.xml
    方法名描述
    String getRealPath(String path)将项目路径转换为实际的磁盘路径。
    • 获取项目上下文路径URLhttp://localhost:8080/myapp/somePagegetContextPath()会返回/myapp
    方法名描述
    String getContextPath()获取项目上下文路径,动态变化的
    • 应用域相关的
    方法名描述
    Object getAttribute(String name)获取指定名称的上下文属性值。
    Enumeration<String> getAttributeNames()获取所有上下文属性的名称。
    void setAttribute(String name, Object value)设置上下文属性的值。
    void removeAttribute(String name)移除指定名称的上下文属性。

4.6 HttpServletRequest

Tomcat将请求报文封装成HttpServletRequest对象,在调用service方法的时候传入该对象,能从中获得所有请求信息。请求报文有哪些属性,就有哪些常用方法,以get系为主,具体可以看源码,不再示例。

4.6 HttpServletResponse

Tomcat在调用service方法的时候传入HttpServletResponse对象,设置完里面的响应报文相关属性之后,Tomcat再将其转换为响应报文返回。常见方法以set系为主,不再示例。

4.7 请求转发

  • 定义:
    请求转发(Request Forwarding)是服务器端将一个请求从一个Servlet转发到另一个Servlet或其他资源的操作。
  • 特点:
    • 通过HttpServletRequest对象获取请求转发器实现
    • 服务器内部实现,客户端不知道,访问地址不变
    • 只产生一对请求和响应对象,请求参数可以传递,对象也会传递到下一个Servlet动态资源或者 WEB-INF下受保护的静态资源,无法转发至项目之外的其他资源。
  • 示例:
    package com.cut.basic;import jakarta.servlet.RequestDispatcher;
    import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;/*** description: 请求转发Demo示例* author: tang* package: com.cut.basic* 2025/1/28 11:41*/
    @WebServlet(name = "requestForwardingDemo",urlPatterns = {"/requestForwarding"}
    )
    public class RequestForwardingDemo extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {RequestDispatcher dispatcher;// Type 1: 请求转发给另一个Servletdispatcher = req.getRequestDispatcher("forwardDestination");req.setAttribute("requestForwardingParams","I'll be back!");// Type 2: 请求转发给WEB-INF下的静态资源(HTML等资源)// dispatcher = req.getRequestDispatcher("WEB-INF/protected.html");// Type 3: 请求转发给外部资源,不可行// dispatcher = req.getRequestDispatcher("www.baidu.com");dispatcher.forward(req, resp);}
    }
    
    package com.cut.basic;import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;/*** description: 请求转发的目的地* author: tang* package: com.cut.basic* 2025/1/28 11:41*/
    @WebServlet(name = "forwardDestination",urlPatterns = {"/forwardDestination"}
    )
    public class ForwardDestination extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String requestForwardingParams = (String) req.getAttribute("requestForwardingParams");resp.getWriter().write(requestForwardingParams);}
    }
    

4.8 响应重定向

  • 定义:响应重定向(Response Redirect)是一种服务器端的操作,用于将客户端的请求重定向到另一个URL
  • 特点:
    • 通过HttpResponse对象的sendRedirect方法实现。
    • 服务端通过302响应码告诉客户端,期间不止一对请求和响应对象, 客户端的地址也会产生变化。
    • 相较于请求转发,响应重定向可以重定向到外部资源,但是不能访问WEB-INF下受保护的资源。
  • 示例:
    略,自己测,就一个sendRedirect方法。

5 Cookie 和Session

5.1 Cookie

  • 定义:
    Cookie 是一种存储在客户端(通常是浏览器)的小型文本文件,用于跟踪用户在网站上的活动或保存用户信息。
  • 特点:
    • 服务端创建Cookie,添加属性后作为响应头的set-cookie属性放入到响应对象中,Tomcat返回给客户端,客户端收到Cookie之后,下次访问这个服务的时候会带上这些信息,Cookie一般不保存敏感信息。
    • 如果Cookie对象调用了setMaxAge(time)方法,那么浏览器关闭不会销毁Cookie,而是会在客户端本地保存time秒。
    • 如果Cookie对象调用了setPath(src)方法,那么客户端在访问该src的时候才会带上这个Cookie对象。

5.2 Session

  • 定义:
    Session 是一种用于在服务器端跟踪用户会话的技术。它允许服务器在多个请求之间保持用户的状态- 信息。每个用户在访问网站时都会被分配一个唯一的会话标识(Session ID),服务器通过这个标识来识别用户的会话。
  • 特点:
    • 服务端在为客户端创建Session的时候会将Session对象的IDJSESSIONIDCookie的方式响应给客户端,在后续访问中客户端会携带这个Cookie
    • 调用getSession()的时候,如果客户端带了ID那么服务端会检查自己有没有,如果没有则创建,如果客户端没带也会创建。不调用是不会创建的,自己动手试试
    • 可以调用setMaxInactiveInterval(time)设置Session的有效时间为time分钟,invalidate()方法可以销毁Session。

6 Filter

6.1 介绍

过滤器(Filter) 是 Java Servlet 规范中定义的一种服务器端组件,用于在请求到达 Servlet 之前或响应返回客户端之前对请求和响应进行拦截和处理。与Servlet类似,定义自己的Filter类继承Filter接口并重写doFilter方法。

  • Filter接口的几个方法
方法名描述
void init(FilterConfig filterConfig)初始化过滤器,由容器在加载过滤器时调用一次。filterConfig 提供了过滤器的初始化参数和上下文信息。
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)每次请求到达时调用,用于对请求和响应进行处理。可以对请求进行预处理,调用 chain.doFilter(request, response) 将请求传递给下一个过滤器或目标资源,也可以对响应进行后处理。
void destroy()在过滤器被卸载时调用,用于释放过滤器占用的资源。
  • 简单示例
    package com.cut.basic;import jakarta.servlet.*;
    import jakarta.servlet.annotation.WebFilter;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;/*** description: 测试过滤器* author: tang* package: com.cut.basic* 2025/1/29*/
    @WebFilter(urlPatterns = {"/hello_annotation"}
    )
    public class FilterDemo implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 父转子得要求该对象确实指向子,这里是可以满足的HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;long t1 = System.currentTimeMillis();filterChain.doFilter(servletRequest, servletResponse);long t2 = System.currentTimeMillis();String redirectInfo = "request " + httpServletRequest.getContextPath() + " use time:" + (t2 - t1) + "ms";try {Thread.sleep(5000);System.out.println(redirectInfo);httpServletResponse.sendRedirect("index.html");} catch (InterruptedException e) {throw new RuntimeException(e);}}
    }
    

6.2 Filter生命周期

阶段对应方法执行时机执行次数
创建对象构造器web应用启动时1
初始化方法void init(FilterConfig filterConfig)构造完毕1
过滤请求void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)每次请求多次
销毁default void destroy()web应用关闭时1次

6.3 Tomcat对Filter接口的实现

Tomcat 中,doFilter 方法传入的 FilterChain 对象是由 Tomcat 容器实现并管理的。具体来说,Tomcat 使用了一个名为 ApplicationFilterChain 的类来实现 FilterChain 接口

public class ApplicationFilterChain implements FilterChain {private final Filter[] filters; // 过滤器数组private final Servlet servlet; // 目标 Servletprivate int index = 0; // 当前处理的过滤器索引public ApplicationFilterChain(Filter[] filters, Servlet servlet) {this.filters = filters;this.servlet = servlet;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {if (index < filters.length) {Filter filter = filters[index];index++; // 准备调用下一个过滤器filter.doFilter(request, response, this); // 递归调用} else {servlet.service(request, response); // 调用目标 Servlet}}
}

通过源码分析,就能理解过滤器链的实现了,通过index管理,妙极!

7 Listener

6.1 介绍

监听器(Listener)是 Java Servlet API 中的一种服务器端组件,用于监听 Web 应用中的各种事件,如会话创建、会话销毁、上下文初始化、上下文销毁等。监听器允许开发者在这些事件发生时执行特定的代码,从而实现对 Web 应用生命周期的管理和控制。

6.2 监听器分类

根据域的不同(请求域,会话域,应用域)可以分为三类监听器:

  • Application域监听器
    • ServletContextListener:监听与整个 Web 应用相关的生命周期事件,如初始化和销毁。
    • ServletContextAttributeListener:监听 ServletContext 对象中属性的添加、删除和替换事件。
  • Session域监听器
    • HttpSessionListener:监听 HTTP 会话的创建和销毁事件。
    • HttpSessionAttributeListener:监听 HTTP 会话中属性的添加、删除和替换事件。
    • HttpSessionBindingListener:监听会话中对象的绑定和解绑事件。
    • HttpSessionActivationListener:监听会话的被动状态变化事件,例如会话从非活动状态变为活动状态。
  • Request域监听器
    • ServletRequestListener:监听 Servlet 请求的初始化和销毁事件。
    • ServletRequestAttributeListener:监听 Servlet 请求中属性的添加、删除和替换事件。

具体示例可以自己查资料,这里不再演示,主要分析监听器的实现原理。

6.3 监听器实现原理

以下是 Tomcat 运行应用服务时,监听器的七个详细步骤:

定义事件源(Event Source)

  • 在 Tomcat 启动时,事件源(如 ServletContextHttpSessionServletRequest)被创建。
  • 事件源是能够触发事件的对象。例如,ServletContext 在 Web 应用启动时被创建,HttpSession 在用户会话创建时被创建,ServletRequest 在每次请求时被创建。

定义事件(Event)

  • 在事件发生时,事件对象(如 ServletContextEventHttpSessionEventServletRequestEvent)被创建。
  • 事件对象封装了事件的详细信息,如事件源、事件类型等。例如,当 ServletContext 初始化时,会创建一个 ServletContextEvent 对象。

定义监听器接口(Listener Interface)

  • 在 Tomcat 启动时,监听器接口(如 ServletContextListenerHttpSessionListenerServletRequestListener)被定义。
  • 监听器接口定义了监听器需要实现的方法,用于处理特定类型的事件。例如,ServletContextListener 接口定义了 contextInitializedcontextDestroyed 方法。

实现监听器(Implement Listener)

  • 在应用开发阶段,开发者实现监听器接口,并在相应的方法中编写处理事件的代码。
  • 开发者实现监听器接口,例如实现 ServletContextListener 接口的类需要实现 contextInitializedcontextDestroyed 方法。

注册监听器(Register Listener)

  • 在 Tomcat 启动时,监听器通过 web.xml 配置文件或注解(如 @WebListener)注册到事件源。
  • 监听器需要在 Web 应用启动时注册到事件源。例如,通过 web.xml 配置文件或注解 @WebListener 注册监听器。

触发事件(Trigger Event)

  • 在事件发生时,事件源会创建一个事件对象,并通知所有注册的监听器。
  • 当事件发生时,事件源会创建一个事件对象,并通知所有注册的监听器。例如,当 ServletContext 初始化时,会创建一个 ServletContextEvent 对象,并通知所有注册的 ServletContextListener

处理事件(Handle Event)

  • 在事件发生时,监听器中相应的方法会被调用,开发者在这些方法中编写的代码将被执行,从而处理事件。
  • 监听器中相应的方法会被调用,开发者在这些方法中编写的代码将被执行,从而处理事件。例如,ServletContextListenercontextInitialized 方法在 ServletContext 初始化时被调用。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/9611.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Baklib揭示内容中台与人工智能技术的创新协同效应

内容概要 在当今信息爆炸的时代&#xff0c;内容的高效生产与分发已成为各行业竞争的关键。内容中台与人工智能技术的结合&#xff0c;为企业提供了一种新颖的解决方案&#xff0c;使得内容创造的流程更加智能化和高效化。 内容中台作为信息流动的核心&#xff0c;能够集中管…

Git进阶之旅:Git 配置信息 Config

Git 配置级别&#xff1a; 仓库级别&#xff1a;local [ 优先级最高 ]用户级别&#xff1a;global [ 优先级次之 ]系统级别&#xff1a;system [ 优先级最低 ] 配置文件位置&#xff1a; git 仓库级别对应的配置文件是当前仓库下的 .git/configgit 用户级别对应的配置文件时用…

Java中的泛型

泛型&#xff1a;是DK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。 泛型的格式&#xff1a;<数据类型> 注意&#xff1a;泛型只能支持引用数据类型。 没有泛型如何储存数据&#xff1a; 弊端&#xff1a;多态不能访问子类的特…

C++/stack_queue

目录 1.stack 1.1stack的介绍 1.2stack的使用 练习题&#xff1a; 1.3stack的模拟实现 2.queue的介绍和使用 2.1queue的介绍 2.2queue的使用 2.3queue的模拟实现 3.priority_queue的介绍和使用 3.1priority_queue的介绍 3.2priority_queue的使用 欢迎 1.stack 1.1stack…

mysql.sock.lock 导致mysql重启失败

背景 今天公司物业断电&#xff0c;导致机房服务器停电宕机&#xff0c;所有的服务都得重启。本着mysql实例都做了服务自启动&#xff0c;所以没有太担心影响开发的日常工作。但是今天一上班开发就找来&#xff0c;各种服务都没起来有问题&#xff0c;数据库连不上。马上登陆数…

Hive:Hive Shell技巧

在终端命令窗口不能直接执行select,creat等HQL命令,需要先进入hive之后才能执行,比较麻烦,但是如果使用Hive Shell就可以直接执行 在终端只执行一次Hive命令 -e 参数, "execute"&#xff08;执行&#xff09;,使用-e参数后会在执行完Hive的命令后退出Hive 使用场景:…

C++:PTA L2-003 月饼

月饼是中国人在中秋佳节时吃的一种传统食品&#xff0c;不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量&#xff0c;请你计算可以获得的最大收益是多少。 注意&#xff1a;销售时允许取出一部分库存。样例给出的情形是这样的&#…

力扣面试150 快乐数 循环链表找环 链表抽象 哈希

Problem: 202. 快乐数 &#x1f469;‍&#x1f3eb; 参考题解 Code public class Solution {public int squareSum(int n) {int sum 0;while(n > 0){int digit n % 10;sum digit * digit;n / 10;}return sum;}public boolean isHappy(int n) {int slow n, fast squa…

春晚舞台上的人形机器人:科技与文化的奇妙融合

文章目录 人形机器人Unitree H1的“硬核”实力传统文化与现代科技的创新融合网友热议与文化共鸣未来展望&#xff1a;科技与文化的更多可能结语 2025 年央视春晚的舞台&#xff0c;无疑是全球华人目光聚焦的焦点。就在这个盛大的舞台上&#xff0c;一场名为《秧BOT》的创意融合…

架构技能(六):软件设计(下)

我们知道&#xff0c;软件设计包括软件的整体架构设计和模块的详细设计。 在上一篇文章&#xff08;见 《架构技能&#xff08;五&#xff09;&#xff1a;软件设计&#xff08;上&#xff09;》&#xff09;谈了软件的整体架构设计&#xff0c;今天聊一下模块的详细设计。 模…

2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文

模型设计思路与创新点&#xff1a; 建模的时候应该先确定我们需要建立什么类的模型&#xff1f;优化类还是统计类&#xff1f;这个题需要大量的数据分析&#xff0c;因此我们可以建立一个统计学模型。 统计学建模思路&#xff1a;观察规律&#xff0c;建立模型&#xff0c;参…

FireFox | Google Chrome | Microsoft Edge 禁用更新 final版

之前的方式要么失效&#xff0c;要么对设备有要求&#xff0c;这次梳理一下对设备、环境几乎没有要求的通用方式&#xff0c;universal & final 版。 1.Firefox 方式 FireFox火狐浏览器企业策略禁止更新_火狐浏览器禁止更新-CSDN博客 这应该是目前最好用的方式。火狐也…

关联传播和 Python 和 Scikit-learn 实现

文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数&#xff1a;集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…

使用 postman 测试思源笔记接口

思源笔记 API 权鉴 官方文档-中文&#xff1a;https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md 权鉴相关介绍截图&#xff1a; 对应的xxx&#xff0c;在软件中查看 如上图&#xff1a;在每次发送 API 请求时&#xff0c;需要在 Header 中添加 以下键值对&a…

万物皆有联系:驼鸟和布什

布什&#xff1f;一块布十块钱吗&#xff1f;不是&#xff0c;大家都知道&#xff0c;美国有两个总统&#xff0c;叫老布什和小布什&#xff0c;因为两个布什总统&#xff08;父子俩&#xff09;&#xff0c;大家就这么叫来着&#xff0c;目的是为了好区分。 布什总统的布什&a…

C++ ——— 仿函数

目录 何为仿函数 仿函数和模板的配合使用 何为仿函数 代码演示&#xff1a; class Add { public:int operator()(int x, int y){return x y;} }; 这是一个 Add 类&#xff0c;类里面有一个公有成员函数重载&#xff0c;重载的是括号 那么调用的时候&#xff1a; Add ad…

Charles 4.6.7 浏览器网络调试指南:流量过滤与分析(六)

1. 概述 在网络调试和优化过程中&#xff0c;Charles 不仅可以实现简单的网络抓包操作&#xff0c;还支持更高级的抓包技巧和流量分析功能。这些功能能够帮助开发者深入挖掘网络请求的细节&#xff0c;为复杂问题提供有效的解决方案。本文将重点讲解 Charles 的过滤规则、自定…

Haproxy入门学习二

一、Haproxy的算法 1.haproxy通过固定参数balance指明对后端服务器的调度算法&#xff0c;其中balance参数可以配置在listen或backend选项中 2.haproxy的调度算法分为静态和动态调度算法&#xff0c;其中有些算法可以根据参数在静态和动态算法中相互转换 3.静态算法&#xff1a…

程序地址空间

程序地址空间回顾&#xff08;这真的是吗&#xff1f;&#xff09; 我们之前学习C/C的时候是否听过&#xff1a;对于自己的C/C程序&#xff0c;我们默认认为自己的内存地址空间是&#xff1a; 代码区&#xff08;Text Segment&#xff09;&#xff1a;存放程序的机器指令代码&…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.21 索引宗师:布尔索引的七重境界

1.21 索引宗师&#xff1a;布尔索引的七重境界 目录 #mermaid-svg-Iojpgw5hl0Ptb9Ti {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Iojpgw5hl0Ptb9Ti .error-icon{fill:#552222;}#mermaid-svg-Iojpgw5hl0Ptb9Ti .…