在 JavaWeb 开发中,Servlet 是核心组件之一,负责处理客户端请求并生成响应。本文将从 Servlet 的基本概念出发,逐步深入其生命周期、实现方式、路径映射等关键知识点,帮助你全面掌握 Servlet 技术。
Servlet(Server Let)是运行在 Web 服务器中的小型 Java 程序,主要作用是处理用户请求。当客户端发出请求后,由 Web 服务器(如 Tomcat)找到对应的 Servlet 进行处理。
JavaWeb 有三大组件,分别是:
其中,Servlet 是最基础、也是必须 100% 掌握的组件。
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 接口并配置访问路径。
package cn.tx.servlet;
import javax.servlet.*;
import java.io.IOException;
public class Servlet1 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
hello
cn.tx.servlet.Servlet1
hello
/hello
Servlet 的生命周期由三个关键方法构成,这些方法会在不同时间点被 Tomcat 调用:
特别说明:
- Servlet 实例默认在第一次请求时创建(可修改)
- 实例由 Tomcat 创建,方法由 Tomcat 调用,我们只需编写实现
- 自定义方法不会被 Tomcat 调用,需由生命周期方法调用
由于多数请求基于 HTTP 协议,Java 提供了HttpServlet
类专门处理 HTTP 请求,它继承自GenericServlet
,而GenericServlet
实现了Servlet
接口。
Servlet(接口)→ GenericServlet(实现类)→ HttpServlet(继承类)
package cn.tx.servlet;
import javax.servlet.http.HttpServlet;
public class Servlet2 extends HttpServlet{
}
然后在 web.xml 中配置映射路径。
通过 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 中配置。
Url-Pattern 的配置有三种方式,优先级为:完全路径匹配 > 目录匹配 > 扩展名匹配
/aaa
、/aaa/bbb
/aaa/*
、/*
*.do
、*.action
/abc/a.html
,/abc/*
比/*
更精确,会调用对应 Servlet/abc
,/abc
(完全匹配)优先于/abc/*
(目录匹配)/abc/a.do
,/abc/*
(目录匹配)优先于*.do
(扩展名匹配)对应 web.xml 中当前 Servlet 的配置信息,可通过init()
方法的参数获取,主要用于获取初始化参数:
hello
cn.tx.servlet.Servlet1
username
root
在代码中获取:
String username = servletConfig.getInitParameter("username");
代表当前 web 应用,所有 Servlet 共享一个ServletContext
对象,服务器启动时创建,关闭时销毁。
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 是单例的,一个实例处理多个请求,因此是线程不安全的。解决方法:不定义可存储数据的属性。
生命周期总结:
init()
方法service()
方法destroy()
方法通过本文的学习,你应该已经掌握了 Servlet 的核心知识,包括其生命周期、实现方式、路径映射等关键内容。Servlet 作为 JavaWeb 的基础,深入理解它对于后续的 Web 开发至关重要。