首页 > 其他分享 >Filter过滤器

Filter过滤器

时间:2023-12-14 13:22:06浏览次数:26  
标签:void throws Filter doFilter 过滤器 public

一 认识过滤器

1.1 什么是过滤器

Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

1.2 过滤器如何实现功能

1在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。

2在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

3 Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,Web服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,doFilter方法中有一个filterChain对象,用于继续传递给下一个filter,在传递之前我们可以定义过滤请求的功能,在传递之后,我们可以定义过滤响应的功能

1.3 过滤器如何使用

采用三步走策略使用filter

1开发后台资源 静态资源(html,css … …)或者动态资源(Servlet,Jsp)

2开发Filter

3在web.xml中配置Filter拦截哪些资源

开发Servlet

public class MyController1 extends HttpServlet {
 @Override
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Mycontroller1的服务方法");
    }
}

开发Filter

自定义类,实现javax.servlet.Filter;接口,重写init,doFilter,destory方法

public class MyFilter1 implements Filter {
 /**
     * 初始化方法
 * @param filterConfig
 * @throws ServletException
     */
 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
 /**
     * 执行过滤的方法
 * @param servletRequest
 * @param servletResponse
 * @param filterChain
 * @throws IOException
     * @throws ServletException
     */
 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 // 过滤请求
 System.out.println("MyFiter1在请求到达servlet之前的代码处理");
 // 传递过滤器
 filterChain.doFilter(servletRequest,servletResponse);
 // 过滤响应
 System.out.println("myFilter1在响应回到浏览器之前的代码处理");
    }
 
 /**
     * 销毁方法
 */
 @Override
 public void destroy() {
 
    }
}

配置Filter和Servlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置servlet-->
    <servlet>
        <servlet-name>mycontroller1</servlet-name>
        <servlet-class>com.bjsxt.controller.MyController1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>mycontroller1</servlet-name>
        <url-pattern>/mycontroller1</url-pattern>
    </servlet-mapping>
    <!--配置filter-->
    <filter>
        <filter-name>myfilter1</filter-name>
        <filter-class>com.bjsxt.filter.MyFilter1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myfilter1</filter-name>
        <!--通过servlet那么确定拦截的资源-->
       <!-- <servlet-name>mycontroller1</servlet-name>-->
        <!--通过请求的映射路径匹配拦截的资源-->
        <url-pattern>/mycontroller1</url-pattern>
    </filter-mapping>
</web-app>

总结:

1在doFilter方法中,我们可以通过filterChain.doFilter方法控制请求是否继续向后传递

2在doFilter方法中,我们同样可以使用HttpRequest处理请求,使用HttpResponse对象作出响应

1.4 过滤器的生命周期

同servlet对象一样,Filter对象的创建也是交给web服务器完成的,在web服务器创建和使用及最后销毁filter时,会调用filter对应的方法

初始化方法:

public void init(FilterConfig filterConfig);

和我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

拦截请求方法

public void doFilter

这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。

销毁方法:

public void destroy();

Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。

测试代码

public class MyFilter1 implements Filter {
 /**
     * 初始化方法
 * @param filterConfig
 * @throws ServletException
     */
 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter1初始化方法");
    }
 
 /**
     * 执行过滤的方法
 * @param servletRequest
 * @param servletResponse
 * @param filterChain
 * @throws IOException
     * @throws ServletException
     */
 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 // 过滤请求
 System.out.println("MyFiter1在请求到达servlet之前的代码处理");
 // 传递过滤器
 filterChain.doFilter(servletRequest,servletResponse);
 // 过滤响应
 System.out.println("myFilter1在响应回到浏览器之前的代码处理");
    }
 
 /**
     * 销毁方法
 */
 @Override
 public void destroy() {
        System.out.println("MyFilter1销毁方法");
    }
}

 

[2020-05-14 07:39:44,981] Artifact myfilter1:war exploded: Artifact is being deployed, please wait...
MyFilter1初始化方法
[2020-05-14 07:39:45,614] Artifact myfilter1:war exploded: Artifact is deployed successfully
[2020-05-14 07:39:45,615] Artifact myfilter1:war exploded: Deploy took 634 milliseconds
MyFiter1在请求到达servlet之前的代码处理
Mycontroller1的服务方法
myFilter1在响应回到浏览器之前的代码处理
D:\program4it\tomcat8\apache-tomcat-8.5.27\bin\catalina.bat stop
Using CATALINA_BASE:   "C:\Users\Mark70\.IntelliJIdea2019.2\system\tomcat\Tomcat_8_5_27_FilterAndListener"
Using CATALINA_HOME:   "D:\program4it\tomcat8\apache-tomcat-8.5.27"
Using CATALINA_TMPDIR: "D:\program4it\tomcat8\apache-tomcat-8.5.27\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk1.8.0_161"
Using CLASSPATH:       "D:\program4it\tomcat8\apache-tomcat-8.5.27\bin\bootstrap.jar;D:\program4it\tomcat8\apache-tomcat-8.5.27\bin\tomcat-juli.jar"
14-May-2020 19:39:58.649 信息 [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
14-May-2020 19:39:58.650 信息 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"]
14-May-2020 19:39:59.245 信息 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"]
14-May-2020 19:39:59.830 信息 [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
MyFilter1销毁方法
14-May-2020 19:39:59.844 信息 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8080"]
14-May-2020 19:39:59.845 信息 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"]
14-May-2020 19:39:59.846 信息 [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-8080"]
14-May-2020 19:39:59.847 信息 [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-8009"]
Disconnected from server

1.5 过滤器链的使用

在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。

web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

使用过滤器链的好处是我们可以将不同的过滤功能分散到多个过滤器中,分工明确,避免一个过滤器做太多的业务处理,降低了代码的耦合度,这体现了单一职责的设计原则,应用了责任链的代码设计模式.

决定过滤器的执行顺序是由fileter-mapping标签决定

测试代码

开发第二个Filter

public class MyFilter2 implements Filter {
 /**
     * 初始化方法
 * @param filterConfig
 * @throws ServletException
     */
 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter2初始化方法");
    }
 
 /**
     * 执行过滤的方法
 * @param servletRequest
 * @param servletResponse
 * @param filterChain
 * @throws IOException
     * @throws ServletException
     */
 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 // 过滤请求
 System.out.println("MyFiter2在请求到达servlet之前的代码处理");
 // 传递过滤器
 filterChain.doFilter(servletRequest,servletResponse);
 // 过滤响应
 System.out.println("myFilter2在响应回到浏览器之前的代码处理");
    }
 
 /**
     * 销毁方法
 */
 @Override
 public void destroy() {
        System.out.println("MyFilter2销毁方法");
    }
}

配置第二个Filter

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置servlet-->
    <servlet>
        <servlet-name>mycontroller1</servlet-name>
        <servlet-class>com.bjsxt.controller.MyController1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>mycontroller1</servlet-name>
        <url-pattern>/mycontroller1</url-pattern>
    </servlet-mapping>
    <!--配置filter-->
    <filter>
        <filter-name>myfilter1</filter-name>
        <filter-class>com.bjsxt.filter.MyFilter1</filter-class>
    </filter>
    <filter>
        <filter-name>myfilter2</filter-name>
        <filter-class>com.bjsxt.filter.MyFilter2</filter-class>
    </filter>
    <!--配置过滤器的拦截映射 这里的配置顺序决定了过滤器的过滤顺序-->
    <filter-mapping>
        <filter-name>myfilter1</filter-name>
        <!--通过servlet那么确定拦截的资源-->
       <!-- <servlet-name>mycontroller1</servlet-name>-->
        <!--通过请求的映射路径匹配拦截的资源-->
        <url-pattern>/mycontroller1</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>myfilter2</filter-name>
        <url-pattern>/mycontroller1</url-pattern>
    </filter-mapping>
</web-app>

1.6 过滤器的初始化参数

同servlet一样,filter也可以通过web.xml进行初始化配置,在初始化是,将参数封装进入FilterConfig并在调用init方法时作为实参传入,我们可以在init方法中获取参数.FilterConfig接口为我们提供了如下功能

String getFilterName();//得到filter的名称。 
String getInitParameter(String name);//返回定名称的初始化参数的值。如果不存在返回null. 
Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 
public ServletContext getServletContext();//返回Servlet上下文对象的引用。

测试代码

在web.xml中配置Filter的初始化参数

<filter>
    <filter-name>myfilter2</filter-name>
    <filter-class>com.bjsxt.filter.MyFilter2</filter-class>
    <init-param>
        <param-name>computer</param-name>
        <param-value>华硕</param-value>
    </init-param>
    <init-param>
        <param-name>RAM</param-name>
        <param-value>金士顿</param-value>
    </init-param>
</filter>

在Filter中获取初始化参数

public class MyFilter2 implements Filter {
 /**
     * 初始化方法
 * @param filterConfig
 * @throws ServletException
     */
 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter2初始化方法");
        String computer = filterConfig.getInitParameter("computer");
        String ram = filterConfig.getInitParameter("RAM");
        System.out.println("computer:"+computer);
        System.out.println("RAM:"+ram);
    }

启动项目测试

Connected to server
[2020-05-14 08:03:02,056] Artifact myfilter1:war exploded: Artifact is being deployed, please wait...
14-May-2020 20:03:02.267 警告 [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used.
MyFilter2初始化方法
computer:华硕
RAM:金士顿

二 过滤器案例开发

1.2 过滤器案例开发之解决post乱码问题

filter可以帮助我们在请求到达servlet之前处理好post乱码问题,这样我们servlet接受的post请求参数是,直接获取参数即可开发form表单

<form action="servlet1" method="post">
  <input type="text" name="username">
  <input type="submit">
</form>

开发后台servlet

@WebServlet("/servlet1")
public class Servlet1  extends HttpServlet{
 @Override
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println("username:"+username);
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("你好");
    }
}

 

开发编码过滤器

public class EncodingFilter implements Filter {
    private String encoding;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //从配置文件中读取编码
        encoding = filterConfig.getInitParameter("charset");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 设置请求编码
        servletRequest.setCharacterEncoding(encoding);
        // 设置响应编码
        servletResponse.setCharacterEncoding(encoding);
        // 传递处理请求
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {

    }
}

配置servlet和Filter

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>com.bjsxt.filter.EncodingFilter</filter-class>
        <init-param>
            <param-name>charset</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/servlet1</url-pattern>
    </filter-mapping>
</web-app>

访问测试:

提交数据

后台接收

返回数据

1.3 过滤器案例开发之登录验证

需求

校验是否登录,如果没有登录执行登录,如果已经登录,那么校验资源

Index 页登录代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="loginCheck" method="post">
      <input type="text" name="username"><br/>
      <input type="password" name="pwd"><br/>
      <input type="submit"><br/>
    </form>
    ${msg}
    <c:remove var="msg" scope="session"></c:remove>
  </body>
</html>

后台servlet代码

@WebServlet("/loginCheck")
public class LoginCheck extends HttpServlet {
 @Override
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        HttpSession session = req.getSession();
        String pwd = req.getParameter("pwd");
 if("尚学堂".equals(username)&&"1234".equals(pwd)){
            User user= new User("sxt","1234","1");
            session.setAttribute("user",user);
            resp.sendRedirect("b.jsp");
        }else if("北京尚学堂".equals(username)&&"4321".equals(pwd)){
            User user= new User("bjsxt","4321","2");
            session.setAttribute("user",user);
            resp.sendRedirect("a.jsp");
        }else{
            session.setAttribute("msg","登录失败");
            resp.sendRedirect("index.jsp");
        }
 
    }
}

过滤器代码

@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /*如果请求的是index.jsp 放行*/
        HttpServletRequest request =(HttpServletRequest)servletRequest;
        HttpServletResponse response =(HttpServletResponse)servletResponse;
        String uri = request.getRequestURI();
        //放行 对于index.jsp 的访问  /loginCheck
        if(uri.contains("index.jsp")||uri.contains("loginCheck")){
            filterChain.doFilter(request,response);
            return;
        }

        /*如果已经登录 完成页面跳转*/
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        if(null != user){ 
            filterChain.doFilter(request,response);
        }else{
            response.sendRedirect("login.jsp");
            return;
 }
    }

    @Override
    public void destroy() {

    }
}

配置filter

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.bjsxt.filter.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>

标签:void,throws,Filter,doFilter,过滤器,public
From: https://www.cnblogs.com/guoyu1/p/17900985.html

相关文章

  • split() 与 filter() 搭配去除符号
    msg1='hello\t\r\nworld'print(''.join(msg1.split()))#这里的split()可以去除所有的制表符,但不能去除一些其它符号。#helloworldmsg='hello----world'print(''.join(filter(None,msg.split('-'))))#helloworldprint('......
  • vue过滤器
    使用场景:加工属性,对属性做一些类似格式化的操作但不会改变该属性;看起来跟computed类似,后面总结两者区别使用地方:可以放在{{}}插值中使用,也可以在v-bind表达式中使用(vue2.1.0+支持)注意事项:过滤器中this不能获取vue实例全局过滤器://main.jsVue.filter('filterFun',function......
  • springboot listener、filter登录实战
    转载自:www.javaman.cn博客系统访问:http://175.24.198.63:9090/front/index登录功能1、前端页面采用的是layui-admin框架,文中的验证码内容,请参考作者之前的验证码功能<!DOCTYPEhtml><htmllang="zh"xmlns:th="http://www.thymeleaf.org"><head><title>ds博客</tit......
  • vue 千分位过滤器
    1.创建numberToCurrency.js文件//千分符过滤器exportfunctionnumberToCurrencyNo(value){if(!value)return0//判断value是否是以0开头的负数if(value<0&&value>-1){returnvalue}else{//将数值截取为小数部分和整数部分constval......
  • Springboot项目实现过滤器功能
    核心类FilterFilter接口的全限定类名是javax.servlet.Filter,该接口有三个方法,分别是1、init(...):用于初始化Filter;2、doFilter(...):过滤请求和拦截响应信息的具体实现在这个方法里;3、destroy(...):Filter对象被销毁时触发,主要用于做一些收尾工作,如资源的释放等;FilterConfigF......
  • 布隆过滤器
    引言面试题如何在10e的数据中,检查用户是否存在?朴素方法:在数据库里直接查,虽然可以建索引,10亿级的数据索引树也大的不得了。这种方式惠产生性能问题,加剧数据库的负载。selectcount(1)fromuser_infowhereuser_id=GGJHAGJH123123123123;缓存方法:SISMEMBERuser_id_key......
  • 算法~布隆过滤器
    布隆过滤器(BloomFilter)是一种高效的概率数据结构,用于判断一个元素是否存在于集合中。它基于位数组和多个哈希函数,并具有以下特点:BloomFilter是一个基于概率的数据结构:它只能告诉我们一个元素绝对不在集合内或可能在集合内快速查询:布隆过滤器具有快速查询的特性。它使用多......
  • 【ASP.NET Core】MVC过滤器:常见用法
    前面老周给大伙伴们演示了过滤器的运行流程,大伙只需要知道下面知识点即可:1、过滤器分为授权过滤、资源访问过滤、操作方法(Action)过滤、结果过滤、异常过滤、终结点过滤。上一次咱们没有说异常过滤和终结点过滤,不过老周后面会说的。对这些过滤器,你有印象就行了。2、所有过滤器接......
  • [Vue] vue学习笔记(5): 过滤器
    关于过滤器注册过滤器:Vue.filter(name,callback)或newVue({filters:{...}})使用过滤器:{{xxx|filter_name}}或v-bind:www="xxx|filter_name"过滤器可以接受除过滤对象以外的其他参数,也可以多个过滤器串联过滤器不会改变原本的数据,而是产生新的数据示例以将js时......
  • 6.6 Windows驱动开发:内核枚举Minifilter微过滤驱动
    Minifilter是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微过滤驱动使用过滤管理器FilterManager提供接口,由于提供了管理结构以及一系列管理API函数,所以枚举过滤驱动将......