Filter

Filter概述

什么是Filter

  • 生活中的过滤器

    净水器、空气净化器、地铁安检、山大王(土匪)

  • web中的过滤器

    当用户访问服务器资源时,过滤器将请求拦截下来,完成一些通用的操作

  • 应用场景

    登录验证、统一编码处理、敏感字符过滤

  • 作用

过滤掉请求的路径

过滤器原理

在这里插入图片描述

在这里插入图片描述

过滤器的快速入门

实现步骤

步骤:
	1. 定义一个类,实现接口Filter,规范.
	2. 重写方法
	3. 配置拦截路径
		1. web.xml
		2. 注解

代码实现

package cn.yanqi.web;

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

/**
 * @Auther: yanqi
 * @Desc
 */
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("--init--");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //默认不会放行
        System.out.println("--doFilter--");
    }

    @Override
    public void destroy() {
        System.out.println("--destroy--");
    }
}

在web.xml中配置过滤器路径

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>cn.yanqi.web.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <!--指定拦截,如配置hello.html路径,这个就拦截进入过滤器中-->
        <!--
	    <url-pattern>/index.jsp</url-pattern>
        <url-pattern>/LoginServlet</url-pattern>
        <url-pattern>/hello.html</url-pattern>-->
        
        <!--拦截所在请求路径-->
        <!--<url-pattern>/*</url-pattern>-->        
    </filter-mapping>

过滤的分析

在这里插入图片描述

Filter生命周期

  • init

    服务器启动项目加载,创建filter对象,执行init方法(只执行一次)

  • doFilter

    用户访问被拦截目标资源时,执行doFilter方法,执行多次

  • destroy

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

过滤器一定是优先于Servlet创建的

Filter生命周期:
	1、当服务器启动时就初始化,并且只初始化一次
	2、每次请求都会走doFilter方法,
	3、服务器正常关闭,Filter销毁 
Servlet生命周期:
	1、用户第一次访问时servlet初始化,并且只初始化一次
	2、每次请求都会走service方法,
	3、服务器正常关闭,Servlet销毁 
	
servlet的生命周期 , filter过滤器的生命周期, 应用用场景和实现接口不一样	

拦截路径

在开发时,我们可以指定过滤器的拦截路径来定义拦截目标资源的范围

  • 精准匹配

    用户访问指定目标资源(/show.html)时,过滤器进行拦截

  • 目录匹配

    用户访问指定目录下(/user/*)所有资源时,过滤器进行拦截

    /user/cart/*

    /user/info/*

  • 后缀匹配

    用户访问指定后缀名(*.html)的资源时,过滤器进行拦截

    /*.html 错误写法

  • 匹配所有

    用户访问该网站所有资源(/*)时,过滤器进行拦截

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>cn.yanqi.web.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    
    <!--指定拦截-->
    <url-pattern>/hello.html</url-pattern>
    <url-pattern>/UserServlet</url-pattern>
    <url-pattern>/show.html</url-pattern>

    <!--匹配后缀-->
    <url-pattern>*.html</url-pattern>

    <!--拦截所有请求路径-->
    <!--<url-pattern>/*</url-pattern>-->

</filter-mapping>

doFilter方法说明

| chain.doFilter(request,response) | 放行 执行后续组件 |

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("======初始化-init=======");
    }

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

        //获取所有请求路径  /login.html   /LoginServlet
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();

        //只放行login.html
        if("/login.html".equals(requestURI)){
            //放行代码
            filterChain.doFilter(servletRequest ,servletResponse);
        }

    }

    @Override
    public void destroy() {
        System.out.println("======销毁-destroy=======");
    }
}

注解方式

/**
 * @Auther: yanqi
 * @Desc  注释方式
 */
// @WebFilter(urlPatterns = "/hello.jsp")
// @WebFilter(urlPatterns = {"/servletDemo","hello.html"})
// @WebFilter(urlPatterns = "*.html")
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

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

    }
    @Override
    public void destroy() {

    }
}

编码过滤器

public class EncodingFilter implements Filter {
    private String encoding;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        encoding = filterConfig.getInitParameter("encoding");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        request.setCharacterEncoding(encoding);
        response.setContentType("text/html;charset=" + encoding);

        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        encoding = null;
    }
}

web.xml

    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>cn.yanqi.web.EncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

用户访问权限的控制

给用户添加URL访问权限

应用场景:搭建在 用户系统完成之后.

系统中存在很多资源,将需要进行权限控制的资源,放入特殊路径中,编写过滤器管理访问特殊路径的请求,如果没有相应身份和权限,控制无法访问

分析: 首先获取客户端请求的资源地址!

基于CustomerManager 系统添加登陆模块

业务分析

 * 1。拦截所有请求路径
 * 2。把通用 login.html list.html... 放行
 * 3。才能判断用户是否登录
 * 4。判断登录的是什么用户
 * 5。如果管理员,放行
 * 6。如果普通用户,如果请求的是什么,我给放了
 * 7。否则不放,告诉用户权限不足

代码实现

修改前面写过的用户管理系统

@WebFilter("/*")
public class MyFilter 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 path   = req.getRequestURI(); //     /login.html  /LoginServlet

            String requestUri = req.getRequestURI();
            if(!("/login2.html".equals(requestUri) || "/loginServlet".equals(requestUri))) {
                //过滤没有登录的情况
                Object user = req.getSession().getAttribute("user");
                if(user == null) {    //没有登录
                    resp.sendRedirect("/login2.html");
                    return;
                }
            }
            //放行
            chain.doFilter(req, resp);
    }

    @Override
    public void destroy() {

    }
}

bject user = req.getSession().getAttribute(“user”);
if(user == null) { //没有登录
resp.sendRedirect(“/login2.html”);
return;
}
}
//放行
chain.doFilter(req, resp);
}

@Override
public void destroy() {

}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值