欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

过滤器Filter

程序员文章站 2024-02-08 18:01:28
...

过滤器

在多个页面需要统一执行的代码,可以通过过滤器的web组件来完成;

  1. 定义过滤器

//识别过滤器
@WebFilter(urlPattern="要过滤哪些路径")
class 过滤器类 implements Filter{
    
    //初始化操作
    public void init(){}
    
    //销毁操作
    public void destroy(){}
    
    //过滤方法
    //FilterChain过滤器链
    public void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain){
        //要统一执行的代码
        
        //是否让请求继续前进
        chain.doFilter(req,resp);
        
    }
}
  1. 过滤的路径格式
  • 精准匹配 /servlet1:只会进入servlet1之前进入过滤器;
  • 后缀匹配 *.jsp:访问任意一个以.jsp结尾的路径都会经过过滤器;
  • 前缀匹配 /user/*:当请求的路径是以user开头的就会经过过滤器;

如果有多个过滤器都和目标路径匹配,那么会依次经过多个过滤器,经过先后顺序跟过滤器的名字有关;

  1. request和response的类型转换

Filter中的request和response声明的是父类型,有些方法没有,需要转换为子类型对象;


  1. 过滤器的应用
  • post请求的中文乱码,可以采用字符编码过滤器来解决
req.setCharacterEncoding("解码字符集");
req.getParameter()
  • 登录检查过滤器
@WebFilter(urlPatterns = "/*")
public class Filter1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        //检查路径是否为登录界面路径,如果是则直接放行,否则判断用户是否已经登录
        String uri = req.getRequestURI();
        if (uri.equals("/users.jsp") || uri.equals("/servlet01")){
            filterChain.doFilter(req,resp);
            return;
        }
        
        //检查会话中是否存在username用户,如果存在这说明已经登录,否则跳转到登录页面让用户继续登录
        HttpSession session = req.getSession();
        Object user = session.getAttribute("username");
        if(user ==null){
            session.setAttribute("error","您尚未登录");
            resp.sendRedirect("/users.jsp");

        }else {
            filterChain.doFilter(req,resp);
        }
    }
    @Override
    public void destroy() {

    }
}

如果跳转页面有多层目录,在跳转时在路径前加上"/",以相对主机名和端口号进行跳转;
否则会以从后往前第一个"/"之前的路径为相对路径进行跳转。

  • 自动登录过滤器
  1. 浏览器第一次登陆,发送登录请求,登陆成功后,服务器将包含用户名、密码的登录标志信息放入session中;
  2. 服务器返回给浏览器一个cookie响应,包含用户名和密码,并且浏览器设置maxAge等属性;
  3. 浏览器关闭,session中的信息失效,但是浏览器中存在cookie的信息,在发送请求的时候,
    同时将cookie中的信息发送给服务器;
  4. 过滤器先检查session内容,如果有旧直接放行,否则检查cookie中的信息,看cookie是否存在并且用户名和密码是否正确,
    如果正确直接放行,否则需要重新登录;

在servlet中判断是否要自动登录

 //如果自动登录栏被勾选则执行
        if (req.getParameter("autoLogin").equals("true")){
            req.setAttribute("success","登陆成功");
            //创建cookie对象,将用户信息存入
            Cookie cookie = new Cookie("up",user.getUsername()+":"+user.getPassword());
            //设置cookie的存活时间
            cookie.setMaxAge(24*3600);
            //将cookie添加到响应,返回给浏览器
            resp.addCookie(cookie);
        }

在过滤器中,先判断session中是否存在用户信息,如果存在则自动登录;如果不存在则判断浏览器发过来的
cookie中是否存在用户信息,如果存在则自动登录,并且把cookie中的信息放入session中方便以后使用,否则跳转到登录页面;

//检查会话中是否存在username用户
        HttpSession session = req.getSession();
        Object user = session.getAttribute("username");
        if(user !=null){
            filterChain.doFilter(req,resp);
        }else {
            //如果session中没有用户信息,则检查cookie中是否存在

            //获取浏览器请求时发过来的cookie
            Cookie[] cookies = req.getCookies();
            Cookie up=null;
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals("up")){
                    up=cookie;
                    break;
                }
            }

            if(up!=null){
                //获取用户名和密码
                String[] split = up.getValue().split(":");
                //验证用户名和密码
                UserDao ud = new UserDao();
                String username = split[0];
                String password=split[1];

                User user1 = ud.authUser(username);
                if (user1!=null && user1.getPassword().equals(password)){
                    //将用户名放入session
                    session.setAttribute("username",username);
                 filterChain.doFilter(req,resp);
                 return;
                }
            }

        }

监听器

Listener没有路径,特定事件发生时,会执行监听器代码;

  • ServletRequestListener:在请求对象初始化和销毁时,会被调用;
  • HttpSessionListener:在session初始化和销毁的时候会被调用;

应用场景:

  • ServletContextListener:在application对象创建和销毁的时候被调用;

  • ServletRequestAttributeListener:在往request作用域中变量发生变化时被调用

  • HTTPSessionAttributeListener:在往session作用域中变量发生变化时被调用

  • ServletContextAttributeListener:在往application作用域中变量发生变化时被调用

  • HttpSessionActivationListener:在session钝化(从内存到磁盘)和活化(从磁盘到内存)session中存储对象,
    对象要实现序列化和反序列化;

  • HTTPSessionBindingListener: