展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

javaweb开发(八):sevlet之filter过滤器

  • filter作用
动态地拦截请求和响应,变换或使⽤包含在请求或响应中的信息
在客户端的请求访问后端资源之前,拦截这些请求
在服务器的响应发送回客户端之前,处理这些响应
  • filter生命周期
init(FilterConfig filterConfig) //只容器初始化的时候调⽤⼀次,即应⽤启动的时候加载⼀次
doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 只要命中
过滤规则就触发,可以在filter中根据条件决定是否调⽤chain.doFilter(request, response)⽅
法, 即是否让⽬标资源执⾏
destroy() //只容器销毁的时候调⽤⼀次,即应⽤停⽌的时候调⽤⼀次
  • 查看源码
package jakarta.servlet;

import java.io.IOException;

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}
  • 自定义filter时,使用@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
  • 自定义filter实践
@WebFilter(filterName = "testFilter",urlPatterns = {"/*"})
public class CustomFilter implements Filter {

    /**
     * filter初始化
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CustomFilter init ");
    }

    /**
     * filter 拦截处理
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("CustomFilter doFilter ");
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        // 请求放行
        chain.doFilter(request,response);
    }

    /**
     * filter销毁的方法
     */
    @Override
    public void destroy() {
        System.out.println("CustomFilter destroy ");
    }

}
  • 测试
# 启动项目时,filter初始化
Connected to server
[2022-04-14 11:12:36,794] Artifact web06:war exploded: Artifact is being deployed, please wait...
14-Apr-2022 11:12:37.891 警告 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom 使用[SHA1PRNG]创建会话ID生成的SecureRandom实例花费了[574]毫秒。
CustomFilter init 
  • 自定义的filter拦截了所有请求,任意访问一个请求,控制台打印如下,说明filter执行了拦截,并放行
http://localhost:8081/get_cookie_test

CustomFilter doFilter 
null
JSESSIONID
47797EAAB1641E2992D93DD3E33C5B21
  • FilterConfig类
过滤器配置类,可以通过这个获取过滤器基本信息
  • 查看源码
package jakarta.servlet;

import java.util.Enumeration;

public interface FilterConfig {
    String getFilterName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}
  • dispatcherTypes参数: 指定Filter对那种dispatcher模式进⾏过滤,不符合的则不进⾏过滤
REQUEST:默认值,浏览器直接请求的资源会被过滤器拦截
FORWARD:转发访问资源会被过滤器拦截
INCLUDE:包含访问资源
ERROR:错误跳转资源
ASYNC:异步访问资源
  • FilterConfig实战
# 编写CustomFilterTest:设置filter名称,要拦截的url,初始化配置,要拦截的类型
# DispatcherType.FORWARD表示转发的时候被拦截
@WebFilter(filterName = "filterTest",urlPatterns = {"/*"},initParams = {
        @WebInitParam(name = "encoding",value = "UTF-8"),
        @WebInitParam(name = "loginPage",value = "/login.jsp"),
},dispatcherTypes = {DispatcherType.FORWARD})

# 编写如下,可在filter的重写的方法中使用默认的属性
private FilterConfig filterConfig;
private String encoding;
private String loginPage;
  • 测试
# 发送一个默认的请求http://localhost:8081/get_cookie_test,控制台打印如下,说明没有进入filter,
null
JSESSIONID
B7AAFF00C73C44DE9ECD1F5FB53681C5

# 发送一个转发的请求http://localhost:8081/forward,控制台打印如下,说明转发类型的请求被拦截了
DispatchServlet doGet
CustomFilter doFilter 
  • filter进行登录拦截
@WebFilter(filterName = "loginFilter",urlPatterns = {"/user/*","/order/*"},initParams = {
        @WebInitParam(name = "encoding",value = "UTF-8"),
        @WebInitParam(name = "loginPage",value = "/login.jsp"),
})
public class LoginFilter implements Filter {

    private FilterConfig filterConfig;

    private String encoding;

    private String loginPage;

    /**
     * filter 初始化
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CustomFilter init ");
        this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");
        this.loginPage = filterConfig.getInitParameter("loginPage");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("CustomFilter doFilter ");
        request.setCharacterEncoding(encoding);
        response.setCharacterEncoding(encoding);
        response.setContentType("text/html;charset=utf-8");
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        // 获取session里的用户信息
        if(httpServletRequest.getSession().getAttribute("loginUser") !=null){
            // 放行
            chain.doFilter(request,response);
        }else {
            httpServletRequest.setAttribute("msg","非法访问,请登录");
            httpServletRequest.getRequestDispatcher(loginPage).forward(httpServletRequest,httpServletResponse);
        }
    }

    /**
     * filter销毁
     */
    @Override
    public void destroy() {
        System.out.println("CustomFilter destroy ");
    }

}
  • 测试,访问登录页面
  • 输入正确的用户名和密码,跳转到user.jsp,控制台打印如下,说明先请求先进入filter初始化 -> loginServlet -> filter过滤器的doFilter()方法
loginServlet doPost
CustomFilter doFilter 

  • 退出登录或未登录状态下直接访问user.jsp,访问失败
http://localhost:8081/user/user.jsp

posted @ 2022-04-14 11:11  DogLeftover  阅读(17)  评论(0编辑  收藏  举报