Servlet概述
在 JavaWeb 开发中,Servlet 是核心组件之一,负责处理客户端请求并生成响应。本文将从 Servlet 的基本概念出发,逐步深入其生命周期、实现方式、路径映射等关键知识点,帮助你全面掌握 Servlet 技术。
一、Servlet 概述与 JavaWeb 三大组件
Servlet(Server Let)是运行在 Web 服务器中的小型 Java 程序,主要作用是处理用户请求。当客户端发出请求后,由 Web 服务器(如 Tomcat)找到对应的 Servlet 进行处理。
JavaWeb 有三大组件,分别是:
- Servlet:处理用户请求的核心组件
- Filter(过滤器):用于对请求和响应进行拦截和处理
- Listener(监听器):基于观察者模式,监听 Web 应用中的事件
其中,Servlet 是最基础、也是必须 100% 掌握的组件。
二、Servlet 接口与核心方法
Servlet 的本质是一个接口(javax.servlet.Servlet
),我们编写的 Servlet 必须实现该接口,并实现其中的 5 个方法:
方法 | 作用 | 特点 |
---|---|---|
void init(ServletConfig servletConfig) | 初始化 Servlet | 仅在 Servlet 实例创建后调用一次,用于初始化工作 |
void service(ServletRequest request, ServletResponse response) | 处理请求 | 每次有请求时都会被调用 |
void destroy() | 销毁 Servlet | Tomcat 关闭时,销毁实例前调用 |
ServletConfig getServletConfig() | 返回 ServletConfig 对象 | 需在 init () 中保存参数后返回 |
String getServletInfo() | 返回 Servlet 说明信息 | 基本无用 |
Tomcat和Servlet的关系
Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上的组件. Servlet最常见的用途是扩展Java Web服务器功能,提供非常安全的,可移植的,易于使用的CGI替代品.
Java Servlet API 是Servlet容器(tomcat)和servlet之间的接口,它定义了serlvet的各种方法,还定义了Servlet容器传送给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。所以说我们在编写servlet时,需要实现Servlet接口,按照其规范进行操作。
注意:Servlet 的实例由 Tomcat 创建和管理,我们只需编写实现类并部署即可。
三、创建第一个 Servlet
创建 Servlet 分为两步:实现 Servlet 接口并配置访问路径。
1. 编写 Servlet 实现类
package cn.tx.servlet;import javax.servlet.*;
import java.io.IOException;public class Servlet1 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}
2. 在 web.xml 中配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><servlet><servlet-name>hello</servlet-name><servlet-class>cn.tx.servlet.Servlet1</servlet-class></servlet><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
</web-app>
四、Servlet 的生命周期
Servlet 的生命周期由三个关键方法构成,这些方法会在不同时间点被 Tomcat 调用:
- init():Servlet 实例创建后立即调用,仅执行一次,用于初始化
- service():每次处理请求时调用,是处理请求的核心方法
- destroy():Tomcat 销毁 Servlet 实例前调用,用于资源释放
特别说明:
- Servlet 实例默认在第一次请求时创建(可修改)
- 实例由 Tomcat 创建,方法由 Tomcat 调用,我们只需编写实现
- 自定义方法不会被 Tomcat 调用,需由生命周期方法调用
五、HttpServlet:处理 HTTP 请求的利器
由于多数请求基于 HTTP 协议,Java 提供了HttpServlet
类专门处理 HTTP 请求,它继承自GenericServlet
,而GenericServlet
实现了Servlet
接口。
1. 继承关系
Servlet(接口)→ GenericServlet(实现类)→ HttpServlet(继承类)
2. 创建 HttpServlet 的两种方式
方式一:手动继承 HttpServlet
package cn.tx.servlet;import javax.servlet.http.HttpServlet;public class Servlet2 extends HttpServlet{}
然后在 web.xml 中配置映射路径。
方式二:使用 IDEA 自动创建
通过 IDEA 的新建 Servlet 功能,会自动生成带有注解的 Servlet 类:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "Servlet3", urlPatterns = "/hello3")
public class Servlet3 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) {}protected void doGet(HttpServletRequest request, HttpServletResponse response) {}
}
注解方式无需在 web.xml 中配置。
六、Servlet 的路径映射
Url-Pattern 的配置有三种方式,优先级为:完全路径匹配 > 目录匹配 > 扩展名匹配
- 完全路径匹配:以 / 开头,如
/aaa
、/aaa/bbb
- 目录匹配:以 / 开头并以 * 结尾,如
/aaa/*
、/*
- 扩展名匹配:不能以 / 开头,如
*.do
、*.action
示例分析
- 对于 URL 为
/abc/a.html
,/abc/*
比/*
更精确,会调用对应 Servlet - 对于 URL 为
/abc
,/abc
(完全匹配)优先于/abc/*
(目录匹配) - 对于 URL 为
/abc/a.do
,/abc/*
(目录匹配)优先于*.do
(扩展名匹配)
七、ServletConfig 与 ServletContext
1. ServletConfig
对应 web.xml 中当前 Servlet 的配置信息,可通过init()
方法的参数获取,主要用于获取初始化参数:
<servlet><servlet-name>hello</servlet-name><servlet-class>cn.tx.servlet.Servlet1</servlet-class><init-param><param-name>username</param-name><param-value>root</param-value></init-param>
</servlet>
在代码中获取:
String username = servletConfig.getInitParameter("username");
2. ServletContext
代表当前 web 应用,所有 Servlet 共享一个ServletContext
对象,服务器启动时创建,关闭时销毁。
主要用途:
- 获取全局初始化参数
- 实现 Servlet 之间的数据共享
- 读取资源文件
示例:统计网站访问次数
protected void doPost(HttpServletRequest request, HttpServletResponse response) {ServletContext servletContext = getServletContext();Integer visitNums = (Integer) servletContext.getAttribute("visitNums");visitNums = visitNums == null ? 0 : visitNums;servletContext.setAttribute("visitNums", ++visitNums);response.getWriter().write("当前网站访问人次:" + visitNums);
}
八、Servlet 的面试要点
单例多线程:Servlet 是单例的,一个实例处理多个请求,因此是线程不安全的。解决方法:不定义可存储数据的属性。
生命周期总结:
- 初始化:调用
init()
方法 - 处理请求:调用
service()
方法 - 销毁:调用
destroy()
方法 - 最终由 JVM 垃圾回收
- 初始化:调用
通过本文的学习,你应该已经掌握了 Servlet 的核心知识,包括其生命周期、实现方式、路径映射等关键内容。Servlet 作为 JavaWeb 的基础,深入理解它对于后续的 Web 开发至关重要。