javaweb之过滤器Filter

一:过滤器拦截原理

Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法。web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法。调用filterChian对象的doFilter方法,web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。相反,如果不调用该方法,web资源不会被访问。

二:Servlet里面的过滤器作用

  • 动态地拦截请求和响应,变换或使用包含在请求或响应中的信息
  • 在客户端的请求访问后端资源之前,拦截这些请求。
  • 在服务器的响应发送回客户端之前,处理这些响应。

三:Filter的生命周期

  • init(FilterConfig filterConfig) //只容器初始化的时候调用一次,即应用启动的时候加载一次
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 只要命中过滤规则就触发,可以在filter中根据条件决定是否调用chain.doFilter(request, response)方法, 即是否让目标资源执行
  • destroy() //只容器销毁的时候调用一次,即应用停止的时候调用一次

四:元注解: @WebFilter

//该Filter是否支持异步操作模式
asyncSupported      
​
//指定Filter对那种dispatcher模式进行过滤 该属性支持 Async,Error Forward,include,request  
dispatcherType  
​
//Filter 显示的名称
displayName    
​
//Filter的名称
filterName    
​
//Filter的配置参数
initParams    
​
//过滤的Servlet可以指定多个,表示对这几个特定的的servlet 进行过滤
servletNames    
​
//指定 Filter拦截的 URL,和上面的servletNames配置一样,用*可以表示通配符,但是不用字母后加*,应该按照模块划分,比如/user/*
urlPatterns/value    

五:过滤器拦截实战

package net.xdclass.web.filter;

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

//@WebFilter(filterName = "xxx", servletNames = {"cookieServlet"},urlPatterns = {"/user/*","/order/*"})
@WebFilter(filterName = "xxx", servletNames = {"cookieServlet"},urlPatterns = {"/get_cookie_test"})
//@WebFilter(filterName = "xxx",urlPatterns = {"/*"})
public class CustomFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CustomFilter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("CustomFilter doFilter");
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html:charset=utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

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

代码讲解:命中/get_cookie_test路径时,会走doFilter里面的逻辑,打印CustomFilter doFilter,命中其他路径时候,均不走doFilter里面的逻辑,不打印CustomFilter doFilter。

六:FilterConfig类

过滤器配置类,可以通过这个获取过滤器基本信息

6.1 dispatcherTypes 参数

  • 指定Filter对那种dispatcher模式进行过滤,不符合的则不进行过滤
    • REQUEST:默认值,浏览器直接请求的资源会被过滤器拦截
    • FORWARD:转发访问资源会被过滤器拦截
    • INCLUDE:包含访问资源
    • ERROR:错误跳转资源
    • ASYNC:异步访问资源

七:实操

DispatchServlet类实现的功能是转发或者重定向,对下述代码中
转发:req.getRequestDispatcher(“/index.jsp”).forward(req,response);
重定向:response.sendRedirect(“/index.jsp”);这两行代码分别注释,查看CustomFilter类实现的效果,主要查看CustomFilter类中的dispatcherTypes参数的作用

package net.xdclass.web.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/forward")
public class DispatchServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {


        System.out.println("DispatchServlet doGet");

        //req.setAttribute("name","xdclass");
        User user = new User();
        user.setHost("https://xdclass.net");
        user.setId(1);
        user.setName("老王");

        //req.setAttribute("user",user);

        req.setAttribute("name","jack");

        req.getRequestDispatcher("/index.jsp").forward(req,response);
//        response.sendRedirect("/index.jsp");
        //response.sendRedirect("https://xdclass.net");

        //req.getRequestDispatcher("request").forward(req,resp);

    }
}

CustomFilter类

package net.xdclass.web.filter;

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

//@WebFilter(filterName = "xxx", servletNames = {"cookieServlet"},urlPatterns = {"/user/*","/order/*"})
//@WebFilter(filterName = "xxx", servletNames = {"cookieServlet"},urlPatterns = {"/get_cookie_test"})
@WebFilter(filterName = "xxx",urlPatterns = {"/*"},initParams = {
        @WebInitParam(name="encoding",value = "UTF-8"),
        @WebInitParam(name="loginPage",value = "/login.jsp"),
},dispatcherTypes = {DispatcherType.FORWARD})
public class CustomFilter implements Filter {

    private FilterConfig filterConfig;

    private String encoding;

    private String loginPage;



    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CustomFilter init");
        this.filterConfig = filterConfig;

        String filterName = filterConfig.getFilterName();
        System.out.println("filterName" + filterName);
        this.encoding = filterConfig.getInitParameter("encoding");
        this.loginPage = filterConfig.getInitParameter("loginPage");

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("CustomFilter doFilter");
        servletRequest.setCharacterEncoding(encoding);
        servletResponse.setCharacterEncoding(encoding);
        servletResponse.setContentType("text/html:charset=utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

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

代码概述:

  • 当DispatchServlet类中req.getRequestDispatcher(“/index.jsp”).forward(req,response);生效时,访问/forward路径,CustomFilter中的doFilter会被触发打印CustomFilter doFilter,因为CustomFilter类中因为dispatcherTypes参数的影响,只有转发的路径才会走doFilter逻辑
  • 当DispatchServlet类中response.sendRedirect(“/index.jsp”);生效时,访问/forward路径,CustomFilter中的doFilter不会被触发不打印CustomFilter doFilter,因为CustomFilter类中因为dispatcherTypes参数的影响,只有转发的路径才会走doFilter逻辑,而现在DispatchServlet类是重定向类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

竹意雅韵(马)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值