广告
返回顶部
首页 > 资讯 > 后端开发 > Python >JavaWeb三大组件之一的Filter详解
  • 456
分享到

JavaWeb三大组件之一的Filter详解

2024-04-02 19:04:59 456人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1. 概念2. 基本使用3. 生命周期4. FilterConfig类5. FilterChain类6. 拦截路径7. ThreadLocal+Filter管理事务7.1 Thr

1. 概念

Filter过滤器是javaweb的三大组件之一。三大组件:Servlet,Listener,Filter

Filter过滤器是JavaEE的规范,即接口

作用:拦截请求,过滤响应

拦截请求常见的应用场景:

  • 权限检查
  • 日记操作
  • 事务管理…

2. 基本使用

例子:要求在你的WEB工程下,有一个admin目录,这个目录下的所有资源(html,jpg,jsp等)都必须是用户登录之后才允许访问。

  • 根据之前我们学的,用户登陆后我们把用户信息保存到Session域中,所以我们判断Session中是否包含有用户信息即可,但这种方案只能用在jsp页面中
  • 使用Filter,可以使用在任何资源上(Filter在获取目标资源前执行)

使用:

写个类去实现Filter接口

// 先写个类去实现javax.servlet.Filter
public class AdminFilter implements Filter {
    // 这个方法重要,主要用于拦截请求!!(权限检查)
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException 
    {
        httpservletRequest req = (HttpServletRequest) servletRequest; // 要强转一下,才能获取Session
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        HttpSession session = req.getSession();  // 获取Session
        Object user = session.getAttribute("user");
        if (user == null) {
            req.getRequestDispatcher("/login.jsp").forward(req, resp); //没登录转发到登陆页面
            return;
        } else {
            // 如果已经登录,如果有下一个Filter则进入,没有则放行,去访问用户请求的资源!(没有这行是不行的)
            filterChain.doFilter(req, resp); 
        }
    }
    // 下面两个可以空实现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }
    @Override
    public void destroy() { }
}

xml配置过滤器(和Servlet差不多)

<!-- 配置过滤器-->
<filter>
    <filter-name>AdminFilter</filter-name>  <!-- 给Filter起一个名称-->
    <filter-class>com.sutong.filter.AdminFilter</filter-class>  <!-- 全类名-->
</filter>
<filter-mapping>
    <filter-name>AdminFilter</filter-name> <!-- 表示当前的拦截路径给哪个Filter使用-->
    <!-- 拦截路径,斜杠表示到工程路径,映射到web目录,admin/* 表示admin目录下全部资源-->
    <url-pattern>/admin/*</url-pattern> 
</filter-mapping>

3. 生命周期

Filter 的方法执行顺序:

  • 构造器 方法
  • init() 初始化方法, 第一二步在web工程启动的时候已经执行(即Filter已经创建)
  • doFilter(),每次拦截到请求就会执行
  • destroy(),停止web的时候执行

4. FilterConfig类

FIlterConfig,Filter过滤器的配置文件类,Tomcat每次创建的Filter的时候,会同时创建一个FilterConfig类。

作用:获取Filter过滤器的配置内容

  • 获取Filter的名称,即配置文件中filter-name标签里面的内容
  • 获取Filter在web.xml中配置的init-param初始化参数 (在filter标签里面配置初始化参数,和Servlet一样)
  • 获取ServletContext对象
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    String filterName = filterConfig.getFilterName(); // 1
    String value = filterConfig.getInitParameter("key1"); // 2
    ServletContext servletContext = filterConfig.getServletContext(); // 3
}

5. FilterChain类

FilterChain 是过滤器链(多个过滤器一起工作)

filterChain.doFilter(req, resp) 该方法是作用:

  • 执行下一个Filter(如果有)
  • 执行目标资源(没有了Filter了)

如果验证通过,执行完目标资源后会返回 doFilter 方法调用的地方,继续执行下面的代码。

当多个过滤器时,拦截同一个文件/目录时,Filter 配置文件的顺序(即web.xml中的配置顺序)决定了每 Filter 的执行顺序,配置在前先执行。

当多个过滤器的特点:⭐

  • 所有的 Filter 和目标资源默认都执行在同一个线程
  • 多个 Filter 共同执行的时候他们都使用一个 Request 对象

6. 拦截路径

精确匹配

<url-pattern>/target.jsp</url-pattern> --> http://ip:port/工程路径/target.jsp

目录匹配

<url-pattern>/admin/*</url-pattern> -> http://ip:port/工程路径/admin/*

后缀名匹配

<url-pattern>*.html</url-pattern> -> 表示要拦截的地址必须以 .html结尾

这个后缀名不一定是现有文件的后缀名,是个字符串就行 *.abc 也行。注意不是以斜杠开头

Filter只关系请求的地址是否匹配,不关心资源是否存在。

7. ThreadLocal+Filter管理事务

7.1 ThreadLocal

ThreadLocal是jdk1.2开始的,作用:可以解决多线程的数据安全问题

ThreadLocal可以给当前线程关联一个数据(可以是普通变量,对象,集合等)

(可以简单理解为,像Map一样,当前线程名为key,关联的数据为value)

如果想要给当前线程关联多个数据则需要多个ThreadLocal实例,ThreadLocal实例一般都是 static 类型,其中保存的数据在线程销毁后由JVM虚拟机自动释放。

// Hashtable线程安全
public static Map<String, Object> map = new Hashtable<>(); 
// ThreadLocal泛型就是关联数据的类型,类似:Map中V的类型,K是当前线程
// 只能关联一个数据,多个则需new多个
public static ThreadLocal<Object> threadLocal = new ThreadLocal<>(); 
// 使用
public void test() {
    map.put(Thread.currentThread().getName(), "Map存数据");
    threadLocal.set("ThreadLocal存数据");
    // 取数据
    Object obj1 = map.get(Thread.currentThread().getName());
    Object obj2 = threadLocal.get();
}

7.2 mysql事务前提

我们在book项目的时候,如果生成订单后发生错误,则生成订单成功而订单详情生成失败,这是严重错误的,所以我们要使用事务确保这些操作在一个事务内。

而确保在一个事务的前期是 使用同一个 Connection 连接对象! 这里就可以用 ThreadLocal 了,把Connection 存到ThreadLocal 中,确保多个Service使用的是同一个连接对象。

而使用 ThreadLocal 关联数据要确保上面这些操作在一个线程中执行! (经过验证我们book中生成订单操作都是在一个线程下的)

String orderId = null;
try {
    orderId = orderService.createOrder(cart, loginUser.getId());
    JdbcUtils.commitAndClose();    // 生成订单,没异常提交事务关闭连接
} catch (Exception e) {
	JdbcUtils.rollbackAndClose();  // 有异常回滚,关闭连接 !!
}
// 但这样做每个xxxService.xxx() 都要进行try catch,太麻烦了,可以使用Filter,看下面

7.3 Filter统一管理

使用Filter统一给所有的 Service 方法都加上 try-catch,来实现管理!!

所有的异常都要抛给 Filter,不要私自处理异常

TransactionFilter.java :

public class TransactionFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
                         FilterChain filterChain) {
        try {
            // 下面这行相当于调用xxxService.xxx()方法,
            // 所以我们对这行进行try-catch就行了(即给所有的Servlet中的所以方法进行了try-catch)
            filterChain.doFilter(servletRequest, servletResponse);
            JdbcUtils.commitAndClose();   // 没异常提交事务,关闭连接
        } catch (Exception e) {
            JdbcUtils.rollbackAndClose();  // 有异常回滚,关闭连接
            e.printStackTrace();           // 可以不打印,打印可以让我们开到什么错误
            throw new RuntimeException(e); // 再把错误抛给Tomcat去显示我们准备的错误页面!!!!!!
            // (如果有异常了,用户页面则会一页空白,我们要给用户一点友好的提示!可以交给Tomcat展示友好的错误页面信息)
        }
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }
    @Override
    public void destroy() { }
}

web.xml

<filter>
    <filter-name>TransactionFilter</filter-name>
    <filter-class>com.sutong.filter.TransactionFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>TransactionFilter</filter-name>
    <url-pattern>/*</url-pattern>  <!-- /* 代表当前工程的所有请求,相当于对工程下的所有请求进行了try-catch-->
</filter-mapping>

7.4 错误信息展示

TransactionFilter.java

try {
    filterChain.doFilter(servletRequest, servletResponse);
    JdbcUtils.commitAndClose(); 
} catch (Exception e) {
    JdbcUtils.rollbackAndClose();       
    throw new RuntimeException(e); // 再把错误抛给Tomcat去显示我们准备的错误页面!!!!!!
    // (如果有异常了,用户页面则会一页空白,我们要给用户一点友好的提示!可以交给Tomcat展示友好的错误页面信息)
}

web.xml配置

<!-- error-page配置服务器出错后,自动跳转的页面-->
<error-page>
    <error-code>500</error-code> <!-- 错误类型-->
    <location>/pages/error/error500.jsp</location> <!-- 要跳转去的页面路径-->
</error-page>
<error-page>
    <error-code>404</error-code> 
    <location>/pages/error/error404.jsp</location> 
</error-page>

到此这篇关于JavaWeb三大组件之一的Filter详解的文章就介绍到这了,更多相关JavaWeb Filter内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaWeb三大组件之一的Filter详解

本文链接: https://www.lsjlt.com/news/151879.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaWeb三大组件之一的Filter详解
    目录1. 概念2. 基本使用3. 生命周期4. FilterConfig类5. FilterChain类6. 拦截路径7. ThreadLocal+Filter管理事务7.1 Thr...
    99+
    2022-11-13
  • Web三大组件之Filter,Listener和Servlet详解
    目录Filter:过滤器Listener:监听器servlet总结Filter:过滤器 1. 概念: * 生活中的过滤器:净水器,空气净化器,土匪、 * web中的过滤器:当访问服...
    99+
    2022-11-13
  • Android四大组件之BroadcastReceiver详解
    BroadcastReceiver是Android四大组件之一,用于接收和处理系统广播或者应用内发送的广播。广播是一种跨组件、跨应用的通信机制,可以用于在应用内部或者应用之间传递消息或者事件。BroadcastReceiver的主要作用...
    99+
    2023-08-09
    Android
  • Java超详细讲解三大特性之一的多态
    目录多态性instanceof 关键字的使用==和equals()区别object类中toString()的使用static关键字的使用总结多态性 1理解多态性:可以理解为一个事物的...
    99+
    2022-11-13
  • Java超详细讲解三大特性之一的继承
    目录继承的概念方法的重写super关键字的使用super调用构造器总结继承的概念 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,...
    99+
    2022-11-13
  • Java超详细讲解三大特性之一的封装
    目录封装封装的概念Java中的包java中类的成员-构造器java中的this关键字总结说到面向对象则不得不提面向对象的三大特征:封装,继承,多态。那么今天就和大家先来介绍什么是封装...
    99+
    2022-11-13
  • Android四大组件之广播BroadcastReceiver详解
    定义 BroadcastReceiver,“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。在Android系统中,广播体现在方方面面,例如当开机完成后系统会产...
    99+
    2022-11-12
  • Android四大组件之broadcast广播详解
    目录基础广播两大类广播广播的动态和静态注册监听时间变化监听系统启动案例创建 receiver设置权限发送自定义广播如何发送与接收有序广播基础广播 两大类广播 标准广播:异步执行,广播...
    99+
    2022-11-13
  • React组件实例三大属性statepropsrefs使用详解
    目录一、 State1.概念2.State的简单用法3. JS绑定事件4.react 绑定事件5.react this指向问题6.修改state值7.代码简写二、props...
    99+
    2022-11-13
  • Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解
    本文实例讲述了Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法。分享给大家供大家参考,具体如下: 我们研究两个问题, 1、S...
    99+
    2022-06-06
    service 调用 方法 activity Android
  • React 三大属性之state的使用详解
    目录类组件函数组件setState的坑 React中很多地方需要用到数据,这在React中被叫做状态,我们需要一个专门管理状态的方法,于是state相关的就诞生了。state应该被要...
    99+
    2022-11-12
  • React三大属性之props的使用详解
    目录类组件函数组件props是只读的 组件间通信 上期讲了state,接下来讲讲props。props功能在于组件间通信(父子组件),首先说说在各种组件中的用法: 类组件 //父...
    99+
    2022-11-12
  • React三大属性之Refs的使用详解
    目录类组件 函数组件面试常问:React中的refs作用是什么? refs是React中用来取得某个JSX组件或者某个DOM中的一些状态值的时候,用来获取节点的方法。在React官方...
    99+
    2022-11-12
  • Android四大组件之Service(服务)实例详解
    本文实例讲述了Android四大组件之服务用法。分享给大家供大家参考,具体如下: 很多情况下,一些与用户很少需要产生交互的应用程序,我们一般让它们在后台运行就行了,而且在它们运...
    99+
    2022-06-06
    service Android
  • Android四大组件之Service服务详细讲解
    目录一、Service是什么二、Service 的启动方式2.1、startService 显示启动Service启动Service 停止2.2、bindService 绑定启动使用...
    99+
    2022-11-13
  • Spring框架中一个有用的小组件之Spring Retry组件详解
    1、概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力。这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助。 在本文中,我们...
    99+
    2022-11-12
  • 三大关系型数据库事务详解之一:基本概念
    一、基本概念   假设用户A要从他的账户里面给B转账1000元,那么就需要两步来实现,首先从A的账号减去1000元,再给B账号加1000元。这两个步骤中,任何一步都不能少或者出错,这两步要么都得到成功操作完成,要么什么都不做,中途...
    99+
    2020-09-12
    三大关系型数据库事务详解之一:基本概念
  • Android组件之服务的详解
    目录一、服务的概念二、Android的多线程编程2.1 线程的基本用法2.2 在子线程中更新UI更新方式一更新方式二2.3 解析异步消息处理机制2.4 使用AsyncTask三、服务...
    99+
    2022-11-12
  • Android12四大组件之Activity生命周期变化详解
    目录前言点击返回键Activity不在onDestroy重新onBackPressed时的注意点总结前言 Android12 有很多令人惊喜的变化,比如基于 Material You...
    99+
    2022-11-13
  • Android系统的四大组件详解
      Android四大基本组件介绍与生命周期   Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,Br...
    99+
    2022-06-06
    Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作