Servlet 三大组件详解

Servlet 三大组件详解

Servlet 三大组件是指 Servlet、Filter(过滤器)和 Listener(监听器),它们是 Java Web 应用开发的核心基础组件,各自承担着不同的职责。下面将详细介绍这三大组件的概念、生命周期、用法和应用场景。

一、Servlet

1. 基本概念

Servlet 是运行在服务器端的 Java 程序,用于处理客户端请求并生成响应。它是连接客户端和服务器端业务逻辑的桥梁,是实现动态网页的核心技术。

2. 主要作用

  • 接收请求:解析客户端发送的 HTTP 请求
  • 处理请求:执行业务逻辑处理
  • 返回响应:生成 HTTP 响应并返回给客户端

3. 生命周期

Servlet 的生命周期分为以下几个阶段:

  1. 实例化:当第一次请求 Servlet 时,Web 容器创建 Servlet 实例(单例模式)
  2. 初始化 :容器调用 init() 方法,只执行一次,用于初始化资源
  3. 服务 :每次请求都会调用 service() 方法,根据请求类型分发到 doGet()doPost() 等方法
  4. 销毁 :服务器关闭或应用卸载时,容器调用 destroy() 方法,释放资源

4. 代码示例

java 复制代码
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

// 使用注解配置
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    
    // 构造器,只调用一次
    public HelloServlet() {
        System.out.println("1. Servlet构造器被调用");
    }
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        System.out.println("2. Servlet初始化");
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello Servlet!</h1>");
        System.out.println("3. 处理GET请求");
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理POST请求
        System.out.println("3. 处理POST请求");
    }
    
    @Override
    public void destroy() {
        System.out.println("4. Servlet销毁");
    }
}

5. 配置方式

注解方式(Servlet 3.0+)
java 复制代码
@WebServlet(
    name = "HelloServlet",
    urlPatterns = "/hello",
    loadOnStartup = 1 // 服务器启动时加载
)
XML 配置方式
xml 复制代码
<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.example.HelloServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

二、Filter(过滤器)

1. 基本概念

Filter 是在客户端和服务器之间的一个过滤层,用于拦截客户端的请求和服务器的响应,实现对请求和响应的预处理和后处理。

2. 主要作用

  • 身份验证:登录验证、权限检查
  • 数据过滤:敏感词过滤、XSS 防护
  • 字符编码处理:统一设置请求和响应的字符编码
  • 日志记录:记录请求信息
  • 响应内容修改:在响应返回客户端前修改内容

3. 生命周期

Filter 的生命周期分为以下几个阶段:

  1. 初始化 :服务器启动时,容器创建 Filter 实例并调用 init() 方法,只执行一次
  2. 过滤 :每次请求被拦截时,容器调用 doFilter() 方法
  3. 销毁 :服务器关闭时,容器调用 destroy() 方法,释放资源

4. 代码示例

java 复制代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")  // 拦截所有请求
public class EncodingFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("1. Filter初始化");
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("2. 执行过滤前的处理");
        
        // 设置请求和响应的字符编码
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        // 放行请求,让请求继续向下执行
        chain.doFilter(request, response);
        
        System.out.println("4. 执行过滤后的处理");
    }
    
    @Override
    public void destroy() {
        System.out.println("5. Filter销毁");
    }
}

5. 配置方式

注解方式
java 复制代码
@WebFilter(
    filterName = "EncodingFilter",
    urlPatterns = {"/*"},  // 拦截所有请求
    initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8")
    }
)
XML 配置方式
xml 复制代码
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.example.EncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

6. 过滤器链

多个过滤器可以组成过滤器链,请求会依次经过每个过滤器。过滤器的执行顺序:

  • XML 配置:按照 <filter-mapping> 标签的顺序执行
  • 注解配置:按照类名的字母顺序执行

三、Listener(监听器)

1. 基本概念

Listener 是用于监听 Web 应用中的事件并触发相应处理的组件。它可以监听 Web 应用的生命周期、Session 的创建和销毁、属性的变化等。

2. 主要类型

ServletContext 监听器
  • ServletContextListener:监听 ServletContext 的创建和销毁
  • ServletContextAttributeListener:监听 ServletContext 属性的变化
HttpSession 监听器
  • HttpSessionListener:监听 Session 的创建和销毁
  • HttpSessionAttributeListener:监听 Session 属性的变化
  • HttpSessionBindingListener:监听对象绑定到 Session 或从 Session 解绑
  • HttpSessionActivationListener:监听 Session 的活化和钝化
ServletRequest 监听器
  • ServletRequestListener:监听请求的创建和销毁
  • ServletRequestAttributeListener:监听请求属性的变化

3. 生命周期

ServletContextListener 为例:

  1. 上下文初始化 :Web 应用启动时,调用 contextInitialized() 方法
  2. 上下文销毁 :Web 应用关闭时,调用 contextDestroyed() 方法

4. 代码示例

java 复制代码
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("1. Web应用启动,初始化上下文");
        // 可以在这里加载配置文件、初始化数据库连接池等
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("2. Web应用关闭,销毁上下文");
        // 可以在这里释放资源,如关闭数据库连接池等
    }
}

5. 配置方式

注解方式
java 复制代码
@WebListener
XML 配置方式
xml 复制代码
<listener>
    <listener-class>com.example.AppListener</listener-class>
</listener>

四、三大组件的调用顺序

在一个完整的请求处理流程中,三大组件的调用顺序如下:

  1. 服务器启动阶段

    • Listener(ServletContextListener)→ Filter → Servlet(如果配置了 load-on-startup)
  2. 请求处理阶段

    • Listener(ServletRequestListener)→ Filter(多个按顺序)→ Servlet → Filter(反向顺序)→ Listener
  3. 服务器关闭阶段

    • Servlet → Filter → Listener(ServletContextListener)

五、在 SpringBoot 中使用三大组件

在 SpringBoot 中使用 Servlet 三大组件需要进行额外配置:

java 复制代码
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfig {
    
    // 注册 Servlet
    @Bean
    public ServletRegistrationBean<HelloServlet> helloServletRegistrationBean() {
        ServletRegistrationBean<HelloServlet> registrationBean = 
            new ServletRegistrationBean<>(new HelloServlet(), "/hello");
        registrationBean.setLoadOnStartup(1);
        return registrationBean;
    }
    
    // 注册 Filter
    @Bean
    public FilterRegistrationBean<EncodingFilter> encodingFilterRegistrationBean() {
        FilterRegistrationBean<EncodingFilter> registrationBean = 
            new FilterRegistrationBean<>(new EncodingFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
    
    // 注册 Listener
    @Bean
    public ServletListenerRegistrationBean<AppListener> appListenerRegistrationBean() {
        return new ServletListenerRegistrationBean<>(new AppListener());
    }
}

六、应用场景总结

组件 主要职责 典型应用场景
Servlet 处理请求,生成响应 用户登录、数据查询、业务处理
Filter 过滤请求和响应 登录验证、字符编码处理、敏感词过滤、日志记录
Listener 监听事件,执行相应操作 应用初始化、资源加载、Session 管理、统计在线人数

七、最佳实践

  1. Servlet

    • 尽量保持 Servlet 简洁,业务逻辑封装到 Service 层
    • 合理使用 loadOnStartup 参数控制初始化时机
  2. Filter

    • 合理设置过滤范围,避免不必要的性能消耗
    • 注意过滤器链的执行顺序
    • 不要在过滤器中执行复杂的业务逻辑
  3. Listener

    • 只在需要监听事件时使用
    • 初始化资源时注意异常处理
    • 确保资源正确释放

Servlet 三大组件是 Java Web 开发的基础,理解它们的工作原理和使用方法对于构建高效、安全的 Web 应用至关重要。

相关推荐
bcbnb4 分钟前
没有 Mac,如何上架 iOS App?跨平台开发者的完整上架实战指南
后端
ZhengEnCi11 分钟前
P3E-Python Lambda表达式完全指南-什么是匿名函数?为什么90%程序员都在用?怎么快速掌握函数式编程利器?
后端·python
DKunYu13 分钟前
1.多线程初阶
java·开发语言
爱分享的鱼鱼17 分钟前
Java基础 (七:网络编程、HTTP客户端开发)(待完善)
后端
尤利乌斯.X20 分钟前
在Java中调用MATLAB函数的完整流程:从打包-jar-到服务器部署
java·服务器·python·matlab·ci/cd·jar·个人开发
spencer_tseng26 分钟前
easy-captcha-1.6.2.jar
java·jar
aiopencode42 分钟前
iOS WebKit Debug Proxy 深度解析与替代方案,跨平台远程调试的新思路
后端
旭编1 小时前
牛客周赛 Round 117
java·开发语言
无敌最俊朗@1 小时前
01-总结
java·jvm·数据库
Java小混子1 小时前
golang项目CRUD示例
开发语言·后端·golang