栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Web基础-Filter过滤器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Web基础-Filter过滤器

1.什么是Filter

它是 JavaWeb 的三大组件之一(三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器)它是 JavaEE 的规范(也就是接口)它的作用是:拦截请求,过滤响应

tips:

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

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


2.Filter初体验

在web工程下,有一个 admin 目录。这个 admin 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必须是用户登录之后才允许访问:

方式1:用户登录之后都会把用户登录的信息保存到Session 域中。所以要检查用户是否登录,可以判断Session中否包含有用户登录的信息即可:

// 在admin目录下的a.jsp

    <%
        Object user = session.getAttribute("user");
        // 如果等于 null,说明还没有登录
        if (user == null) {
            request.getRequestDispatcher("/login.jsp").forward(request,response);
            return;
        }
    %>
    I am a.jsp

// web目录下的login.jsp

    login.jsp页面

​ 未登录的状态下输入http://localhost:8080/book/admin/a.jsp则会转发到login.jsp中。但是对于a.html这种方式实现不了,因为html页面不能写Java代码

方式2:使用Filter:

public class AdminFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object user = session.getAttribute("user");
        // 如果等于 null,说明还没有登录
        if (user == null) {
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
            return;
        }else {
            // 让程序继续往下访问用户的目标资源
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}
// web.xml


    
    AdminFilter
    
    com.psj.filter.AdminFilter



    
    AdminFilter
    
    /admin/*


3.Filter的生命周期

Filter 的生命周期包含几个方法:

    构造器方法init 初始化方法:第 1,2 步在 web 工程启动的时候执行(Filter 已经创建)doFilter 过滤方法:每次拦截到请求,就会执行destroy 销毁:停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)

4.FilterConfig类

Filter过滤器的配置文件类Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息FilterConfig 类的作用是获取 filter 过滤器的配置内容:

获取 Filter 的名称 filter-name 的内容,使用FilterConfig中的getFilterName()获取在 Filter 中配置的 init-param 初始化参数,使用FilterConfig的getInitParameter("xxx")获取 ServletContext 对象,使用FilterConfig的getServletContext()


5.FilterChain过滤器链

FilterChain即过滤器链(多个过滤器如何一起工作)

tips:

在下图中,如果Filter1没有执行chain.doFilter方法是不会执行Filter2的doFiter中的所有代码的


6.Filter的拦截路径

Filter的拦截路径有三种匹配方法:

精确匹配:

/target.jsp,表示请求地址必须为http://ip:port/工程路径/target.jsp 目录匹配:

/admin/*,表示请求地址必须为http://ip:port/工程路径/admin/* 后缀名匹配:

*.html,表示请求地址必须以.html 结尾才会拦截到

tips:

Filter它只关心请求的地址是否匹配,不关心请求的资源是否存在,所以采用后缀名匹配时可以写任意后缀名如.abc


7.ThreadLocal 7.1 概念和特点

可以解决多线程的数据安全问题可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)可以像 Map 一样存取数据,key 为当前线程每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个ThreadLocal 对象实例每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型ThreadLocal 中保存数据,在线程销毁后。会由 JVM 虚拟自动释放

7.2 入门
// 不使用ThreaddLocal
public class ThreadLocalTest {
    public final static Map data = new ConcurrentHashMap<>();
    private static Random random = new Random();

    public static class Task implements Runnable {

        @Override
        public void run() {
            // 随机生成一个变量(即线程要关联的数据),然后以当前线程为key保存到Map中
            int i = random.nextInt(1000);
            String name = Thread.currentThread().getName();
            System.out.println("线程[" + name + "]生成的随机数是:" + i);
            data.put(name, i);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 该线程执行其他类的方法,但是和线程绑定的数据也是能在执行该方法时获取到
            new OrderService().createOrder();
            
            Object o = data.get(name);
            System.out.println("在线程["+name+"]快结束时取出关联的数据是:" + o);

        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Task()).start();
        }
    }
}
// OrderService类
public class OrderService {
    public void createOrder() {
        String name = Thread.currentThread().getName();
        System.out.println("OrderService 当前线程[" + name + "]中保存的数据是:" +
                ThreadLocalTest.data.get(name));
    }
}
// 打印内容如下:
线程[Thread-1]生成的随机数是:291
线程[Thread-2]生成的随机数是:198
线程[Thread-0]生成的随机数是:837
OrderService 当前线程[Thread-2]中保存的数据是:198
OrderService 当前线程[Thread-0]中保存的数据是:837
OrderService 当前线程[Thread-1]中保存的数据是:291
在线程[Thread-1]快结束时取出关联的数据是:291
在线程[Thread-2]快结束时取出关联的数据是:198
在线程[Thread-0]快结束时取出关联的数据是:837
// 使用ThreadLocal,简化了代码
public class ThreadLocalTest {
    // public final static Map data = new ConcurrentHashMap<>();
    public static ThreadLocal threadLocal = new ThreadLocal();
    private static Random random = new Random();

    public static class Task implements Runnable {

        @Override
        public void run() {
            // 随机生成一个变量(即线程要关联的数据),然后以当前线程为key保存到Map中
            int i = random.nextInt(1000);
            String name = Thread.currentThread().getName();
            System.out.println("线程[" + name + "]生成的随机数是:" + i);
            // data.put(name, i);
            threadLocal.set(i);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new OrderService().createOrder();
            // Object o = data.get(name);
            Object o = threadLocal.get();
            System.out.println("在线程[" + name + "]快结束时取出关联的数据是:" + o);

        }
    }
}
public class OrderService {
    public void createOrder() {
        String name = Thread.currentThread().getName();
        System.out.println("OrderService 当前线程[" + name + "]中保存的数据是:" +
                ThreadLocalTest.threadLocal.get());
    }
}
 
 
7.3 实际使用 

tips:

如上图中可以看到,假设在Dao层中出现异常,如果直接捕获了异常,则在Service层等就不会有异常,就无法执行到catch代码块中的rollback,所以在Dao中可以捕获异常,但是也要向外抛出一个异常,或者直接向外抛出异常


8.Filter和ThreadLocal的结合

执行filterChain.doFilter()方法因为会调用目标资源,当调用的目标资源是html是就返回页面给客户端,当调用的目标资源时Servlet程序时,就相当于执行Servlet中的代码内容


9.配置错误页面
// web.xml


    
    500
    
    /pages/error/error500.jsp



    
    404
    
    /pages/error/error404.jsp


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号