Java学习之Filter与Listener篇

Java学习之Filter与Listener篇0x00前言在一些登录点或者是登录后才能使用的一些功能点里面,需要该用户登录后才去才能去访问或使用这些功能。但我们如果每个servlet都去进行一个

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

Java学习之Filter与Listener篇

0x00 前言

在一些登录点或者是登录后才能使用的一些功能点里面,需要该用户登录后才去才能去访问或使用这些功能。但我们如果每个servlet都去进行一个判断是否登录,这些会有很多重复代码,而且效率也比较低。那么我们可以把这些代码都放到Filter过滤器里面去进行编写。

web里面有三大组件:servlet、Filter、Listener。

下来会来写Filter和Listener的相关内容。

0x01 Filter 过滤器

filter作用:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。

一般用于完成一些统一的操作,比如登录验证。

定义步骤:

1. 定义一个类,实现接口Filter
2. 复写方法
3. 配置拦截路径

配置拦截路径有2种方式,分别是web.xml和注解进行配置。

注解配置拦截路径


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilerDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterdemo执行");
        filterChain.doFilter(servletRequest, servletResponse);  //放行


    }

    @Override
    public void destroy() {

    }
}


web.xml 配置拦截路径

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>demo1</filter-name>  //声明名字
        <filter-class>cn.test.web.filter.FilerDemo1</filter-class> //声明对应的filter过滤器
    </filter>

    <filter-mapping>
        <filter-name>demo1</filter-name>
        <url-pattern>/*</url-pattern>     //声明filter拦截资源
    </filter-mapping>
</web-app>

这里可以看到filter类,需要重写3个方法,这里的三个方法的作用分别是:


1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源

2. doFilter:每一次请求被拦截资源时,会执行。执行多次

3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源

服务器会先执行过滤器,再执行过滤器放行的资源,最好再执行过滤器放行后面的代码。

上面的代码直接拦截了所有的资源,定义的时候过滤器有多种的定义方式

1. 具体资源路径: /index.jsp   只有访问index.jsp资源时,过滤器才会被执行

2. 拦截目录: /user/*	访问/user下的所有资源时,过滤器都会被执行

3. 后缀名拦截: *.jsp		访问所有后缀名为jsp资源时,过滤器都会被执行

4. 拦截所有资源:/*		访问所有资源时,过滤器都会被执行

我们可以将后台的一些功能servlet定义为amdin/addUserserlvlet,定义多一层目录,拦截器可以直接定义拦截路径为admin/*这样,如果携带了登录的session后,才选择放行。

定义拦截方式

注解里面定义拦截路径,默认是REQUEST方式,也就是浏览器直接访问,使用转发或者或者是其他这些方式访问一样是会被拦截器给拦截的。

如果我们需要使用转发访问资源不被拦截器拦截,可以在注解中配置dispatcherTypes属性的值。

dispatcherTypes 五种属性:

1. REQUEST:默认值。浏览器直接请求资源

2. FORWARD:转发访问资源

3. INCLUDE:包含访问资源

4. ERROR:错误跳转资源

5. ASYNC:异步访问资源

代码:

package cn.test.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(value = "/*",dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})  //定义浏览器请求和转发拦截器被执行
public class FilerDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterdemo执行");
        filterChain.doFilter(servletRequest, servletResponse);  //放行


    }

    @Override
    public void destroy() {

    }
}

如果是在web.xml里面进行配置,那么我们只需要加入


REQUEST

web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>demo1</filter-name>
        <filter-class>cn.test.web.filter.FilerDemo1</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>demo1</filter-name>
        <url-pattern>/*</url-pattern>

        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

</web-app>

登陆过滤器案例:

package cn.test.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter("/*")
public class loginFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            System.out.println(req);
            //强制转换成 HttpServletRequest
            HttpServletRequest request = (HttpServletRequest) req;

            //获取资源请求路径
            String uri = request.getRequestURI();
            //判断是否包含登录相关资源路径,排除掉 css/js/图片/验证码等资源
            if(uri.contains("/login.jsp") || uri.contains("/loginServlet") || uri.contains("/css/") || uri.contains("/js/") || uri.contains("/fonts/") || uri.contains("/checkCodeServlet")  ){
                //包含,用户就是想登录。放行
                chain.doFilter(req, resp);
            }else{
                //不包含,需要验证用户是否登录
                //从获取session中获取user
                Object user = request.getSession().getAttribute("user");
                if(user != null){
                    //登录了。放行
                    chain.doFilter(req, resp);
                }else{
                    //没有登录。跳转登录页面

                    request.setAttribute("login_msg","您尚未登录,请登录");
                    request.getRequestDispatcher("/login.jsp").forward(request,resp);
                }
            }


            // chain.doFilter(req, resp);
        }
    

    public void init(FilterConfig config) throws ServletException {

    }

}

0x02 Listener 监听器

事件监听机制:

* 事件	:一件事情

* 事件源 :事件发生的地方

* 监听器 :一个对象

* 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码

listener 监听器实现:

首先我们需要实现ServletContextListener的接口,该接口并没有一个定义好的实现类,需要自己进行定义。

ServletContextListener方法:

* void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法

* void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法

代码:

@WebListener
public class ContextLoadListeter implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();   
        String contextConfig = servletContext.getInitParameter("configLocation");  //获取configLocation的参数
        String realPath = servletContext.getRealPath(contextConfig);  //获取路径
        try {
            FileInputStream ifs = new FileInputStream(realPath);  //读取文件
            System.out.println(ifs);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }


    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("listeter被销毁");
    }
}

web.xml配置:

 <context-param>
        <param-name>configLocation</param-name>
        <param-value>/WEB-INF/config.xml</param-value>
    </context-param>

监听器一般用于默认加载资源。

0x03 结尾

Filter与Listener篇完结。

Java学习之Filter与Listener篇

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119935.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 嵌入式Linux移植USB网卡驱动「建议收藏」

    嵌入式Linux移植USB网卡驱动「建议收藏」硬件平台:realARM6410操作系统:fedorakernel2.6.33.3-85.fc13.i686.PAE交叉编译器:arm-none-linux-gnueabigccversion4.3.2WIFI模组:磊科NW336芯片realtek8188cus

    2022年9月24日
    5
  • win10 1分钟自动重启_windows7一分钟后自动重启

    win10 1分钟自动重启_windows7一分钟后自动重启前言Charles是收费软件,可以免费试用30天。试用期过后,未付费的用户仍然可以继续使用,但是每次使用时间不能超过30分钟,并且启动时将会有10秒种的延时。此时,我们只需网上找一个注册码即可解

    2022年7月31日
    6
  • php多线程webservice,PHP有适用于高并发的WebService框架嘛?[通俗易懂]

    php多线程webservice,PHP有适用于高并发的WebService框架嘛?[通俗易懂]现在的nodejs项目很火,ruby语言也出现了像sinatra,Padrino之类的webservice框架,PHP语言有没有类似的框架啊?回复内容:现在的nodejs项目很火,ruby语言也出现了像sinatra,Padrino之类的webservice框架,PHP语言有没有类似的框架啊?swoole_framework可以试试http://www.slimframework.com/与si…

    2022年9月21日
    2
  • linux usb audio没声音,ubuntu16.04安装后没有声音?

    linux usb audio没声音,ubuntu16.04安装后没有声音?问题描述安装完ubuntu16.04后,查看声音设置,貌似是原本笔记本用的驱动没有了,当前显示的这个是因为外接了显示器,如果把线拔掉,这里就空的了.基础信息1.uname~$uname-aLinuxxps4.10.0-27-generic#30~16.04.2-UbuntuSMPThuJun2916:07:46UTC2017x86_64x86_64x86_64GN…

    2025年8月7日
    2
  • ⁉️socket实现Ping命令打造⚡BOSS来了⚡摸鱼神器⭐干货巨多❤️建议收藏❤️

    ⁉️socket实现Ping命令打造⚡BOSS来了⚡摸鱼神器⭐干货巨多❤️建议收藏❤️大家好,我是????前面我写了篇水文《获取当前局域网下所有连接设备的ip地址和mac地址》,但是没有想到的是居然上了热榜,也是我个人第一篇上热榜的文章,阅读量瞬间飙升????。然而我的硬核技术文却几乎没有人看到。既然又很多人对这个话题感兴趣,那么我们就继续对相关原理深挖,最好能自己实现,理解透彻。首先我们回顾一下前文,在前文中我介绍了windows下获取ip地址和arp映射表的命令,通过分析最新arp映射表知道当前网段下在线或下线的设备⭐。文章使用的技术是通过python调用系统ping命令,实现ar

    2022年7月14日
    12
  • java类加载器是什么_类加载器有几种

    java类加载器是什么_类加载器有几种类加载器是有了解吗?解析:底层原理的考察,其中涉及到类加载器的概念,功能以及一些底层的实现。答:顾名思义,类加载器(classloader)用来加载Java类到Java虚拟机中。一般来说,Java虚拟机使用Java类的方式如下:Java源程序(.java文件)在经过Java编译器编译之后就被转换成Java字节代码(.class文件)。类加载器负责读取Java…

    2022年8月11日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号