Java-servlet(十)使用过滤器,请求调度程序和Servlet线程(附带图谱表格更好对比理解)

发布于:2025-03-29 ⋅ 阅读:(27) ⋅ 点赞:(0)


前言

  • 在前几篇博客中,我们学习了 Servlet 的基础配置、生命周期、请求响应处理以及 Java Servlet 环境的配置
  • 接下来,我们将深入探讨 Servlet 间通信、Servlet 响应的相关方法、Servlet 线程模型以及 Servlet 过滤器等重要内容

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的Java-servlet文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12907265.html?spm=1001.2014.3001.5482


一、Servlet 间通信(了解即可)

  • Servlet 间通信可以通过请求分配器对象来实现,它实际上是一种转发机制
  • 比如在一个 Web 应用中,当用户请求一个 Servlet 时,该 Servlet 可能需要将请求转发给另一个 Servlet 进行进一步处理。这在多个 Servlet 协同完成一个复杂功能时非常有用
  • 例如,一个 Servlet 负责接收用户的登录请求,验证用户名和密码后,将请求转发给另一个 Servlet 来处理登录成功后的页面跳转或权限分配等操作。

二、Servlet 请求处理:getAttribute 和 getParameter 的区别与应用

  • 在处理 HTTP 请求时Servlet 提供了多种方法来获取请求数据和设置响应内容
  • 其中, getAttribute 和 getParameter 是两个常用的方法,它们的作用和使用方式有所不同。

一句话记忆

  • getAttribute拿自己人(服务器)的数据
  • getParameter拿外人(用户)的数据
 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("doPost"+req.getParameter("name"));

        String username=(String) req.getAttribute("name");
        String username1= req.getParameter("name");
        resp.getWriter().write("getAttribute"+username+"---getParameter"+username1);
    }
  • 例如上面代码中的
String username=(String) req.getAttribute("name");
String username1= req.getParameter("name");

1.getAttribute 方法

getAttribute 方法用于从请求中获取属性值
这些属性可以是其他 Servlet 或过滤器设置的,也可以是我们在当前 Servlet 中设置的。例如:

request.setAttribute("username", "张三");
String username = (String) request.getAttribute("username");

  • 在这个例子中,我们首先通过 setAttribute 方法将一个属性 username 设置到请求中,然后通过 getAttribute 方法获取这个属性的值。

2.getParameter 方法

getParameter 方法用于从请求中获取用户提交的表单参数。例如,用户在登录表单中输入了用户名和密码,我们可以通过 getParameter 方法获取这些参数

String username = request.getParameter("username");
String password = request.getParameter("password");

这两个方法的区别在于getAttribute 获取的是请求中的属性,而 getParameter 获取的是用户提交的表单参数。在实际开发中,我们需要根据具体需求选择合适的方法

对比项 getAttribute getParameter
作用 从请求中获取属性值(可用于Servlet间传递数据) 从请求中获取用户提交的表单参数(如URL参数或表单输入)
数据来源 服务器端通过setAttribute设置的数据 客户端(浏览器)发送的请求参数(如HTML表单、URL查询字符串)
数据类型 可以是任意Java对象(需强制类型转换) 始终是字符串类型(即使表单中输入的是数字)
使用场景 在多个Servlet/JSP之间共享数据(如登录后的用户信息) 处理用户输入(如登录验证、表单提交)
示例代码 request.setAttribute("user", userObject);
User user = (User) request.getAttribute("user");
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
注意事项 需手动进行类型转换 若参数不存在则返回null,需处理空值情况

简单总结

  • getAttribute:用于服务器内部数据传递(如A Servlet处理完数据后传递给B Servlet)。
  • getParameter:用于获取用户输入数据(如表单提交的用户名、密码)。

一句话记忆

  • getAttribute拿自己人(服务器)的数据
  • getParameter拿外人(用户)的数据

三、Servlet线程模型

  • 在 Java Web 应用中,Servlet 的线程模型是一个非常重要的概念。
  • 它决定了 Servlet 如何处理并发请求,以及如何管理线程资源
  • 常见的线程模型有两种:多线程模型和单线程模型

多线程模型

  • 多线程模型是 Servlet 的默认线程模型。
  • 在这种模型下,每个请求都会被分配到一个独立的线程中处理。
  • 这种方式的优点是可以同时处理多个请求,提高应用的响应速度
  • 然而,多线程模型也存在一些缺点,比如线程安全问题。
  • 由于多个线程可能会同时访问共享资源,如果没有进行适当的同步处理,可能会导致数据不一致等问题

单线程模型

  • 单线程模型通过实现 SingleThreadModel 接口来实现。
  • 在这种模型下,Servlet 的每个实例只会被一个线程访问,从而避免了线程安全问题。然
  • 而,单线程模型也有其缺点,比如性能较低。由于每次只能处理一个请求,当请求量较大时,可能会导致应用响应缓慢

以下是 Servlet 线程模型的对比表格

对比项 多线程模型 单线程模型
线程处理方式 每个请求分配独立线程,并发处理多个请求 同一时间仅一个线程处理请求(排队执行)
默认情况 是(Servlet 的默认行为) 否(需手动实现 SingleThreadModel 接口)
优点 响应速度快,支持高并发 无需处理线程安全问题
缺点 需自行处理线程安全(如同步代码块) 性能低,请求量大时易阻塞
适用场景 高并发 Web 应用(如电商网站、社交平台) 线程安全敏感但并发量低的场景(如简单管理后台)
注意事项 共享资源(如成员变量)需同步控制 Servlet 2.4 后 SingleThreadModel 已废弃,推荐使用其他线程安全方案(如局部变量)

一句话总结

  • 多线程模型:快但需小心线程安全。
  • 单线程模型:安全但性能差,已过时。

四、servlet过滤器(重点)

  • 过滤器是 Java-servlet 中的一个重要特性,它可以对请求和响应进行拦截和处理
  • 过滤器的作用非常广泛,比如可以用于日志记录、权限校验、请求编码设置等

4.1 过滤器的作用

  • 过滤器的主要作用是对请求和响应进行预处理和后处理。
  • 例如,在请求到达 Servlet 之前,过滤器可以对请求进行校验,如果用户没有登录,可以直接返回错误信息,而不需要让请求到达 Servlet
  • 在响应返回给客户端之前,过滤器也可以对响应内容进行处理,比如添加一些额外的信息

4.2 过滤器的使用场景

过滤器的使用场景非常多,以下是一些常见的场景:

  • 日志记录:记录请求的详细信息,方便后续的分析和排查问题。
  • 权限校验:检查用户是否具有访问某个资源的权限。
  • 请求编码设置:设置请求的编码格式,避免出现乱码问题。
  • 响应压缩:对响应内容进行压缩,减少传输数据量。

4.3. 实现过滤器链

过滤器链是指多个过滤器按照一定的顺序依次对请求和响应进行处理。在 Java-servlet 中,可以通过实现 Filter 接口并注册多个过滤器来实现过滤器链。以下是一个简单的例子:

// FilterDemo1
public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化过滤器
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("执行了过滤器-FilterDemo1");
        chain.doFilter(request, response); // 将请求传递给下一个过滤器或 Servlet
    }

    @Override
    public void destroy() {
        // 销毁过滤器
    }
}

在 doFilter 方法中, chain.doFilter(request, response) 语句用于将请求传递给下一个过滤器或 Servlet。通过这种方式,多个过滤器可以依次对请求和响应进行处理。

4.4. 配置文件优先级

在 Java-servlet 中,过滤器的配置可以通过 web.xml 文件或注解来完成。如果同时使用了 web.xml 文件和注解,配置文件的优先级会高于注解。以下是一个 web.xml 文件的配置示例:

<filter>
    <filter-name>filter2</filter-name>
    <filter-class>filter.FilterDemo2</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter2</filter-name>
    <url-pattern>/index</url-pattern>
</filter-mapping>

<filter>
    <filter-name>filter1</filter-name>
    <filter-class>filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/index</url-pattern>
</filter-mapping>

<filter>
    <filter-name>filter3</filter-name>
    <filter-class>filter.FilterDemo3</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter3</filter-name>
    <url-pattern>/index</url-pattern>
</filter-mapping>

  • 在上面的配置中, filter1 、 filter2 和 filter3 是三个过滤器,它们都会对 /index 路径的请求进行处理。过滤器的执行顺序由 filter-mapping 的配置顺序决定

核心概念速记

  • Servlet 间通信要点
    • 借助请求分配器对象实现转发机制。
    • 适用于多个 Servlet 协同完成复杂功能场景,如登录验证与后续处理的转发。
  • 请求处理方法区别
    • getAttribute:获取服务器内部设置的属性值,数据类型为任意 Java 对象(需强制类型转换),用于 Servlet 间数据共享。
    • getParameter:获取用户提交的表单参数,数据类型为字符串,用于处理用户输入。
  • 线程模型特性
    • 多线程模型:默认模型,每个请求分配独立线程,能并发处理请求但需处理线程安全问题,适用于高并发场景。
    • 单线程模型:实现 SingleThreadModel 接口(已废弃),同一时间仅一个线程处理请求,无线程安全问题但性能低,适用于并发量低且线程安全敏感场景。
  • 过滤器关键应用
    • 对请求和响应进行拦截和处理,可用于日志记录、权限校验、请求编码设置、响应压缩等。
    • 实现过滤器链,多个过滤器按顺序处理请求和响应,配置文件(web.xml)优先级高于注解,过滤器执行顺序由 filter-mapping 配置顺序决定。

Java-servlet 相关对比

对比项 getAttribute getParameter 多线程模型 单线程模型
数据来源 服务器端设置的数据 客户端发送的请求参数 每个请求分配独立线程 同一时间仅一个线程处理请求
数据类型 任意 Java 对象(需强制类型转换) 字符串 支持高并发 性能低,请求量大时易阻塞
使用场景 Servlet 间共享数据 处理用户输入 高并发 Web 应用 线程安全敏感但并发量低的场景
注意事项 需手动进行类型转换 若参数不存在则返回 null,需处理空值情况 共享资源需同步控制 Servlet 2.4 后已废弃,推荐其他线程安全方案

知识图谱

Java-servlet(十) 使用过滤器,请求调度程序和 Servlet 线程  
├─ Servlet 间通信  
│  └─ 请求分配器对象实现转发  
├─ 请求处理方法  
│  ├─ getAttribute(拿服务器数据)  
│  └─ getParameter(拿用户数据)  
├─ 线程模型  
│  ├─ 多线程模型(默认,快但需线程安全处理)  
│  └─ 单线程模型(已废弃,安全但性能差)  
├─ 过滤器  
│  ├─ 作用(请求响应拦截处理)  
│  ├─ 使用场景(日志、权限、编码、压缩)  
│  ├─ 实现过滤器链(多个过滤器按序处理)  
│  └─ 配置文件优先级(`web.xml` 高于注解)  
└─ 关键术语  
   ├─ 请求分配器、`getAttribute`、`getParameter`  
   ├─ 多线程模型、`SingleThreadModel`  
   └─ 过滤器、`Filter`、`filter-mapping`  

重点提炼

  1. Servlet 间通信

    • 理解请求分配器的转发机制,用于 Servlet 间协同工作。
    • 实际应用中合理利用转发,优化业务逻辑处理流程。
  2. 请求处理方法

    • 明确 getAttributegetParameter 的区别,根据需求正确选择使用。
    • 注意 getAttribute 的类型转换和 getParameter 的空值处理。
  3. 线程模型

    • 掌握多线程模型的并发处理优势和线程安全问题。
    • 了解单线程模型的原理及废弃原因,避免错误使用。
  4. 过滤器应用

    • 熟悉过滤器的多种使用场景,在项目中合理应用以提升系统功能。
    • 掌握过滤器链的实现和配置文件优先级,正确配置过滤器顺序。
  5. 技术实践要点

    • 在处理并发请求时,对共享资源进行同步控制,确保数据一致性。
    • 配置过滤器时,根据实际需求和优先级选择合适的配置方式。

以上就是这篇博客的全部内容,下一篇我们将继续探索 Java-servlet 的更多精彩内容。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的Java-servlet文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12907265.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述