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. 代码示例

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+)
@WebServlet(
    name = "HelloServlet",
    urlPatterns = "/hello",
    loadOnStartup = 1 // 服务器启动时加载
)
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. 代码示例

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. 配置方式

注解方式
@WebFilter(
    filterName = "EncodingFilter",
    urlPatterns = {"/*"},  // 拦截所有请求
    initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8")
    }
)
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. 代码示例

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. 配置方式

注解方式
@WebListener
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 三大组件需要进行额外配置:

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 应用至关重要。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]