【JAVA】过滤器基础知识以及验证登录

过滤器

  • 过滤器怎么构造?
    package com.sj.www;
    
    import jakarta.servlet.*;
    import jakarta.servlet.annotation.WebFilter;
    
    import java.io.IOException;
    
    /**
     * "*.do"这种写法不用以/开头
     * 这种写法属于模糊匹配中的拓展匹配,以星号开始就不要以斜杠开头
     * 还一种写法是/dept/*
     * 星号表示任意,所以上面那种写法是匹配所有以/dept/开头的路径
     */
    @WebFilter("*.do")
    public class Filter1 implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("Filter的init方法被执行了");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("doFiterl方法被执行了");
            /*执行下一个过滤器,如果没有过滤器,那么就按请求路径执行Java程序*/
            filterChain.doFilter(servletRequest,servletResponse);
        }
    
        @Override
        public void destroy() {
            System.out.println("过滤器被销毁了");
        }
    }
    
    • 注意: Filter的优先级,天生的就比Servlet优先级高。

      • /a.do对应一个Filter, 也对应一个Servlet。
        那么一定是先执行Filter,然后再执行Servlet。|

      • 目标Servlet是否执行, 取决于两个条件: .
        第一:在过滤器当中是否编写了: chain.doFilter(request, response);代码。
        第二:用户发送的请求路径是否和Servlet的请求路径- 致。
        chain.doilter(request, response);这行代码的作用:执行下一个过滤器,如果下面没有过滤器了,执行最终的Servlet.

  • filter是有优先级的,当存在多个filter的时候。
    • 使用xml:filter-mapping的顺序决定了谁先执行,越靠上优先级越高。
    • 使用注解:按照类的名字在字典中的顺序执行。
    • 并且是最先执行的那个filter最后才结束doFilter方法。
  • Filter的生命周期
    • 和servlet对象声明周期一致
    • 唯一不同就是filter在服务器启动阶段 实例化,servlet不会
    • /a 对应了一个servlet和一个filter,它一定会先执行filter,在考虑执行servlet
  • Filter设计模式:责任链设计模式
    • 先执行过滤器1的代码,然后跳到过滤器2,在跳到过滤器3…过滤器n,最后没有过滤器了跳到指定路径的Java中执行完Java程序,在回到过滤器n的doFilter方法中,执行完剩下的程序,然后过滤器n执行完,回到过滤器n-1执行完剩下的程序…就是这个意思。
    • 在编译阶段就确定了调用关系,如果你想改变他们的调用顺序,必须修改Java代码顺序,显然是违背了开闭原则的,但是过滤器是可以在xml里面通过改变mapping的顺序来调整执行的顺序,不需要改源代码,属于是改善了这种设计模式。
  • Filter虽然是接口,但是我们可以不重写init和desico方法,因为他们带default(默认)标记,可以不重写。

  • 怎么让任何项目都得通过filter验证呢,url里面设置为 /*
<filter>
    <filter-name>filter</filter-name>
    <filter-class>com.sj.www.LoginCheckFilter</filter-class>
</filter>
<!--只要你访问的路径是/下面的,你都要走我过滤器-->
<filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 过滤器功能代码
package com.sj.www;

import jakarta.servlet.*;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

public class LoginCheckFilter implements Filter {
    /*测试使用count*/
    int count=0;
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) servletRequest;
        HttpServletResponse response=(HttpServletResponse) servletResponse;
        HttpSession session = request.getSession(false);
        boolean flag=false;
        Cookie[] cookies = request.getCookies();
        if (cookies !=null){
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("loginuser")){
                    flag=true;
                }
            }
        }
        /*
        * 请求的是哪个页面不能拦截
        * 1、用户进入网站的welcome页面不能过滤掉,不能让客户一进你网站,就让人家登录
        * 2、过滤器的else一定不要拦截,否则就等于自己拦截自己,无限循环导致重定向过多
        * 3、index.jsp也不能过滤掉,因为你/Welcome没登陆的没cookie的时候跳转的就是这个index.jsp页面,给别人展示一些
        * 内容的外加登录功能,你不能用户想看你首页,你得登录,显然是不合适得
        * 总结有些页面你不想让用户,直接就进去的,就写在if条件里,只有满足这个条件才能进
        * 如果是index和login好的你可以直接进,如果你想进的是/oa/list不好意思,验证是否登录,登录过了就通过
        *
        * 一些不需要登录的,可以写在if里,一些登录的验证可以写在if条件里
        * */
        String servletPath = request.getServletPath();
        if ("/Welcome".equals(servletPath)||"/index.jsp".equals(servletPath)||"/login.jsp".equals(servletPath)||session != null && session.getAttribute("username") != null||flag) {
            filterChain.doFilter(request,response);
        }else{
            /*
            * 没有通过上面的条件,就被过滤掉了,就走下面
            *
            /*否则就跳到登录页面*/
            System.out.println("过滤器被调用"+(++count)+"次");
            response.sendRedirect(request.getContextPath()+"/login.jsp");
        }
    }
}
  • 什么情况下不能拦截 ?

过滤器if里面写的:1、你网站的首页index2、如果你的首页是个Java程序(在Java程序执行一段程序后(跳转到首页)那么这个路径和index都要放在里面3、else里跳转的页面也要放到if里(否则浏览器会循环到里面导致重定向过多次))

目前写的路径是: /*表示所有的请求均拦截。
1、用户访问index. jsp的时候不能拦截(因为欢迎页跳转到的是这里,而且index一般都不拦截)
2、用户已经登录了,这个需要放行,不能拦截。
3、用户要去登录,这个也不能拦截。
4、WelcomeServlet也不能拦截,因为这是欢迎页。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Keyle777

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值