Filter(过滤器)

Filter过滤器它的作用是:拦截请求,过滤响应。

过滤器链
1)执行的顺序依次是: A B C Demo03 C2 B2 A2
2)如果采取的是注解的方式进行配置,那么过滤器链的拦截顺序是按照全类名的先后顺序排序的

  

@WebFilter("*.do")

3)如果采取的是xml的方式进行配置,那么按照配置的先后顺序进行排序

  精确匹配:<url-pattern>/target.jsp</url-pattern>

  目录匹配:<url-patten>/admin/*</url-pattern>

  后缀名匹配:<url-pattern>*.do</url-pattern>//请求地址必须以.do结尾才会拦截到(add.do)

  Filter过滤器它只关心请求的地址是否匹配,而不关心请求的资源是否存在!

ThreadLocal(本地线程)

  • 主要方法:get() , set(obj),remove()
  • ThreadLocal称之为本地线程 。 我们可以通过set方法在当前线程上存储数据、通过get方法在当前线程上获取数据

set方法源码分析:

     public void set(T value) {
Thread t = Thread.currentThread(); //获取当前的线程
ThreadLocalMap map = getMap(t); //每一个线程都维护各自的一个容器(ThreadLocalMap)
if (map != null)
map.set(this, value); //这里的key对应的是ThreadLocal,因为我们的组件中需要传输(共享)的对象可能会有多个(不止Connection)
else
createMap(t, value); //默认情况下map是没有初始化的,那么第一次往其中添加数据时,会去初始化
}

get方法源码分析:

     public T get() {
Thread t = Thread.currentThread(); //获取当前的线程
ThreadLocalMap map = getMap(t); //获取和这个线程(企业)相关的ThreadLocalMap(也就是工作纽带的集合)
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this); //this指的是ThreadLocal对象,通过它才能知道是哪一个工作纽带
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value; //entry.value就可以获取到工具箱了
return result;
}
}
return setInitialValue();
}

remove方法源码分析:

     public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread()); //获取当前的线程
if (m != null)
m.remove(this);//删除此线程
}

使用Filter和ThreadLocal组合管理

ConnUtil.class

package fruit.dao.base;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class ConnUtil {
private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();
public static final String DRIVER = "com.mysql.jdbc.Driver" ;
public static final String URL = "jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&characterEncoding=utf-8&useSSL=false";
public static final String USER = "root";
public static final String PWD = "a1814995041" ; public static Connection createConn(){
try {
//1.加载驱动
Class.forName(DRIVER);
//2.通过驱动管理器获取连接对象
return DriverManager.getConnection(URL, USER, PWD);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return null;
} public static Connection getConn(){
Connection conn=threadLocal.get();
if (conn == null) {
conn=createConn();
threadLocal.set(conn);
}
return threadLocal.get();
} public static void closeConn() throws SQLException {
Connection conn=threadLocal.get();
if (conn==null){
return;
}if(!conn.isClosed()){
conn.close();
threadLocal.set(null);
}
}
}

TransactionManger.class

package myssm.trans;

import fruit.dao.base.ConnUtil;
import java.sql.Connection;
import java.sql.SQLException; public class TransactionManger { //开始事务
public static void beginTrans() throws SQLException{
ConnUtil.getConn().setAutoCommit(false);
} //提交事务
public static void commit() throws SQLException {
Connection conn = ConnUtil.getConn();
conn.commit();
ConnUtil.closeConn();
} //回滚事务
public static void rollback() throws SQLException {
Connection conn = ConnUtil.getConn();
conn.rollback();
ConnUtil.closeConn();
}
}

OpenSessionInViewFilter.class

package myssm.fiflters;

import myssm.trans.TransactionManger;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.sql.SQLException; @WebFilter("*.do")
public class OpenSessionInViewFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try{ TransactionManger.beginTrans();
System.out.println("开始事务");
filterChain.doFilter(servletRequest,servletResponse);
TransactionManger.commit();
System.out.println("提交事务");
}catch (Exception e){
e.printStackTrace();
try {
TransactionManger.rollback();
System.out.println("回滚事务");
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
} @Override
public void destroy() { }
}

Listener(监听器)

常用Listener
  1) ServletContextListener - 监听ServletContext对象的创建和销毁的过程
  2) HttpSessionListener - 监听HttpSession对象的创建和销毁的过程
  3) ServletRequestListener - 监听ServletRequest对象的创建和销毁的过程

  4) ServletContextAttributeListener - 监听ServletContext的保存作用域的改动(add,remove,replace)
  5) HttpSessionAttributeListener - 监听HttpSession的保存作用域的改动(add,remove,replace)
  6) ServletRequestAttributeListener - 监听ServletRequest的保存作用域的改动(add,remove,replace)

  7) HttpSessionBindingListener - 监听某个对象在Session域中的创建与移除
  8) HttpSessionActivationListener - 监听某个对象在Session域中的序列化和反序列化

ServletContextListener的应用 - ContextLoaderListener(上下文的监听器)

  • ServletContextListener:可以监听ServletContext对象的创建和销毁。
  • ServletContext 对象在web工程启动的时候创建,在web工程停止的时候销毁。
public class ListenerTest implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了"); } @Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了");
}

与上面的项目对应(使用Filter和ThreadLocal组合管理)

ContextLoaderListener.class

package myssm.listeners;

import myssm.io.BeanFactory;
import myssm.io.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener; @WebListener
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//1.获取ServletContext对象(上下文)
ServletContext application=servletContextEvent.getServletContext();
//2.获取上下文的初始化参数
String path=application.getInitParameter("contextConfigLocation");
//3.创建IOC容器
BeanFactory beanFactory=new ClassPathXmlApplicationContext(path);
//4.将IOC容器保存到application作用域中
application.setAttribute("beanFactory",beanFactory);
} @Override
public void contextDestroyed(ServletContextEvent servletContextEvent) { }
}

web.xml

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/com/applicationContext.xml</param-value>
</context-param>

Filter(过滤器)、ThreadLocal(本地线程)、Listener(监听器)的更多相关文章

  1. ThreadLocal本地线程变量的理解

     一般的Web应用划分为展现层.服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用.在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程.       ...

  2. Java 类 ThreadLocal 本地线程变量

    前言:工作中将要使用ThreadLocal,先学习总结一波.有不对的地方欢迎评论指出. 定义 ThreadLocal并不是一个Thread,而是Thread的局部变量.这些变量不同于它们的普通对应物, ...

  3. Flask中的ThreadLocal本地线程,上下文管理

    先说一下和flask没有关系的: 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程对同一块 ...

  4. ThreadLocal = 本地线程?

    一.定义 ThreadLocal是JDK包提供的,从名字来看,ThreadLocal意思就是本地线程的意思. 1.1 是什么? 要想知道他是个啥,我们看看ThreadLocal的源码(基于JDK 1. ...

  5. Java Concurrency - ThreadLocal, 本地线程变量

    共享数据是多线程应用最常见的问题之一,但有时我们需要为每个线程保存一份独立的变量.Java API 提供了 ThreadLocal 来解决这个问题. 一个 ThreadLocal 作用的例子: imp ...

  6. 过滤器(Filter)、拦截器(Interceptor)、监听器(Listener)

    一.Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servle ...

  7. Listener监听器和Filter过滤器

    Listener监听器 WEB中的监听器 WEB 中的 Listener 和 Filter 是属于 Servlet 规范中的高级的技术.WEB中的监听器共有三类八种(监听三个域对象)* 事件源:Ser ...

  8. 15 Filter过滤器和Listener监听器

    1.Filter:过滤器 (1) 概念:生活中的过滤器:净水器,空气净化器,土匪.web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能.过滤器的作用:一般用于完成通用的 ...

  9. Filter过滤器Listener:监听器

    Filter过滤器 1. 概念 web中的过滤器:当访问服务器资源是,过滤器可以将请求拦截下来,完成一些特殊功能: 过滤器的作用 完成通用的操作:例如登录验证.统一编码处理.敏感字符过滤... 快速入 ...

随机推荐

  1. Camunda如何配置和使用mysql数据库

    Camunda默认使用已预先配置好的H2数据库,数据库模式和所有必需的表将在引擎第一次启动时自动创建.如果你想使用自定义独立数据库,比如mysql,请遵循以下步骤: 一.新建mysql数据库 为Cam ...

  2. SSMS设置为深色模式

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2022年2月8日. 2022年4月16日:SSMS很好用,但现在我更多使用DataGrip了. 2022年6月11日:S ...

  3. 最简单的离散概率分布,伯努利分布 《考研概率论学习之我见》 -by zobol

    上文讲了离散型随机变量的分布,我们从最简单的离散型分布伯努利分布讲起,伯努利分布很简单,但是在现实生活中使用的很频繁.很多从事体力工作的人,在生活中也是经常自觉地"发现"伯努利分布 ...

  4. JavaScript产生随机颜色

    //获取rgb类型的颜色 IE7不支持 function randomColor(){ var r = Math.floor(Math.random()*256); var g = Math.floo ...

  5. python基础知识-day9(数据驱动)

    1.数据驱动的概念 在自动化测试中,需要把测试的数据分离到JSON,YAML等文件中. 2.YAML 的相关知识 YAML 入门教程 分类 编程技术 YAML 是 "YAML Ain't a ...

  6. 业务可视化-让你的流程图"Run"起来

    前言 最近在研究业务可视化的问题,在日常的工作中,流程图和代码往往是分开管理的. 一个被维护多次的系统,到最后流程图和代码是否匹配这个都很难说. 于是一直有一个想法,让程序直接读流程图,根据流程图的配 ...

  7. springboot项目上传存储图片到七牛云服务器

    springboot项目上传存储图片到七牛云服务器 问题描述: 当图片存在本地时会出现卡顿的现象.比如一篇图文混排的文章,如果图片没有加载完,可能整个文章都显示不出来,因为它们都是用的同一个服务器. ...

  8. P3480 [POI2009]KAM-Pebbles 题解

    题目链接 首先,这道题看上去就是个博弈论,很显然的 \(Nim\) 游戏. 因为每一个的取法都和它的上一位有关. 有一种非常显然的转换方式 :我们把这若干堆石子从前向后做一个差分 . 我们记 \(a_ ...

  9. PostgreSQL的查询技巧: 零除, GENERATED STORED, COUNT DISTINCT, JOIN和数组LIKE

    零除的处理 用NULLIF(col, 0)可以避免复杂的WHEN...CASE判断, 例如 ROUND(COUNT(view_50.amount_in)::NUMERIC / NULLIF(COUNT ...

  10. HDFS、Yarn、Hive…MRS中使用Ranger实现权限管理全栈式实践

    摘要:Ranger为组件提供基于PBAC的鉴权插件,供组件服务端运行,目前支持Ranger鉴权的组件有HDFS.Yarn.Hive.HBase.Kafka.Storm和Spark2x,后续会支持更多组 ...