[Java]过滤器(Filter)

这篇具有很好参考价值的文章主要介绍了[Java]过滤器(Filter)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、什么是过滤器

过滤器是Servlet的高级特性之一,是实现Filter接口的Java类!
过滤器的执行流程:

java filter,servlet,java,开发语言

 

从上面的图我们可以发现,当浏览器发送请求给服务器的时候,先执行过滤器,然后才访问Web的资源。服务器响应Response,从Web资源抵达浏览器之前,也会途径过滤器。

过滤器的用途:过滤一些敏感的字符串【规定不能出现敏感字符串】、避免中文乱码【规定Web资源都使用UTF-8编码】、权限验证【规定只有带Session或Cookie的浏览器,才能访问web资源】等等等。

也就是说:当需要限制用户访问某些资源时、在处理请求时提前处理某些资源、服务器响应的内容对其进行处理再返回、我们就是用过滤器来完成的!

二、过滤器的一般用途

1.解决中文乱码问题

只要在过滤器中指定了编码,可以使全站的Web资源都是使用该编码,并且重用性是非常理想的!

public class CharacterEncodingFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        chain.doFilter(request, response);

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

web.xml配置:

<filter>
   <filter-name> CharacterEncodingFilter</filter-name>
  <filter-class>com.entor.filter.CharacterEncodingFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name> CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

2.过滤器 API

只要Java类实现了Filter接口就可以称为过滤器!Filter接口的方法也十分简单:

java filter,servlet,java,开发语言

其中init()和destory()方法就不用多说了,他俩跟Servlet是一样的。只有在Web服务器加载和销毁的时候被执行,只会被执行一次!

值得注意的是doFilter()方法,它有三个参数(ServletRequest,ServletResponse,FilterChain),从前两个参数我们可以发现:过滤器可以完成任何协议的过滤操作!

java filter,servlet,java,开发语言

FilterChain是一个接口,里面又定义了doFilter()方法。这究竟是怎么回事啊??????

我们可以这样理解:过滤器不单单只有一个,那么我们怎么管理这些过滤器呢?在Java中就使用了链式结构。把所有的过滤器都放在FilterChain里边,如果符合条件,就执行下一个过滤器(如果没有过滤器了,就执行目标资源)。

上面的话好像有点拗口,我们可以想象生活的例子:现在我想在茶杯上能过滤出石头和茶叶出来。石头在一层,茶叶在一层。所以茶杯的过滤装置应该有两层滤网。这个过滤装置就是FilterChain,过滤石头的滤网和过滤茶叶的滤网就是Filter。在石头滤网中,茶叶是属于下一层的,就把茶叶放行,让茶叶的滤网过滤茶叶。过滤完茶叶了,剩下的就是茶(茶就可以比喻成我们的目标资源)

三、快速入门

写一个简单的过滤器
实现Filter接口的Java类就被称作为过滤器

    public class FilterDemo1 implements Filter {
        public void destroy() {
        }

        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

            //执行这一句,说明放行(让下一个过滤器执行,如果没有过滤器了,就执行执行目标资源)
            chain.doFilter(req, resp);
        }

        public void init(FilterConfig config) throws ServletException {

        }
    }

1.filter部署

过滤器和Servlet是一样的,需要部署到Web服务器上的。

  • 第一种方式:在web.xml文件中配置
   <filter>
             <filter-name>FilterDemo1</filter-name>
             <filter-class>FilterDemo1</filter-class>
             <init-param>
             <param-name>word_file</param-name> 
             <param-value>/WEB-INF/word.txt</param-value>
             </init-param>
    </filter>

   <filter-mapping>
        <filter-name>FilterDemo1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

<filter>用于注册过滤器

  • <filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
  • <filter-class>元素用于指定过滤器的完整的限定类名。
  • <init-param>元素用于为过滤器指定初始化参数,它的子元素

<filter-mapping>元素用于设置一个Filter 所负责拦截的资源。

  • <filter-name>子元素用于设置filter的注册名称。该值必须存在
  • <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
  • 第二种方式:通过注解配置
//@Component//无需添加此注解,在启动类添加@ServletComponentScan注解后,会自动将带有@WebFilter的注解进行注入!
@WebFilter(urlPatterns = "/lvjia/carbodyad/api/*", filterName = "rest0PubFilter")
@Order(1)//指定过滤器的执行顺序,值越大越靠后执行
public class Rest0PubFilter implements Filter {
 
 
    @Override
    public void init(FilterConfig filterConfig) {//初始化过滤器
         System.out.println("getFilterName:"+filterConfig.getFilterName());//返回<filter-name>元素的设置值。
         System.out.println("getServletContext:"+filterConfig.getServletContext());//返回FilterConfig对象中所包装的ServletContext对象的引用。
         System.out.println("getInitParameter:"+filterConfig.getInitParameter("cacheTimeout"));//用于返回在web.xml文件中为Filter所设置的某个名称的初始化的参数值
         System.out.println("getInitParameterNames:"+filterConfig.getInitParameterNames());//返回一个Enumeration集合对象。
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,             
         FilterChain filterChain) throws IOException, ServletException {
         if(false){
             response.sendRedirect("http://localhost:8081/demo/test/login");//重定向
         }
         filterChain.doFilter(servletRequest, servletResponse);//doFilter将请求转发给过滤器链下一个filter , 如果没有filter那就是你请求的资源
 
 }
 
    @Override
    public void destroy() {
    }
 
}
@SpringBootApplication
@ServletComponentScan   //Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

 

@WebFilter常用属性

属性 类型 是否必需 说明
asyncSupported boolean 指定Filter是否支持异步模式
dispatcherTypes DispatcherType[] 指定Filter对哪种方式的请求进行过滤。支持的属性:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST;默认过滤所有方式的请求
filterName String Filter名称
initParams WebInitParam[] 配置参数
displayName String Filter显示名
servletNames String[] 指定对哪些Servlet进行过滤
urlPatterns/value String[] 两个属性作用相同,指定拦截的路径

过滤器的urlPatterns的过滤路径规则:

  • 全路径匹配: /abc/myServlet1.do
  • 部分路径匹配: /abc/*
  • 通配符匹配 :/*
  • 后缀名匹配 :*.do (注意:前面不加/)

2.过滤器的执行顺序

上面已经说过了,过滤器的doFilter()方法是极其重要的,FilterChain接口是代表着所有的Filter,FilterChain中的doFilter()方法决定着是否放行下一个过滤器执行(如果没有过滤器了,就执行目标资源)。

四、Filter简单应用

filter的三种典型应用:

  • 可以在filter中根据条件决定是否调用chain.doFilter(request, response)方法,即是否让目标资源执行
  • 在让目标资源执行之前,可以对request\response作预处理,再让目标资源执行
  • 在目标资源执行之后,可以捕获目标资源的执行结果,从而实现一些特殊的功能

1.禁止浏览器缓存所有动态页面

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

        //让Web资源不缓存,很简单,设置http中response的请求头即可了!

        //我们使用的是http协议,ServletResponse并没有能够设置请求头的方法,所以要强转成HttpServletRequest

        //一般我们写Filter都会把他俩强转成Http类型的
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        response.setDateHeader("Expires", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");

        //放行目标资源的response已经设置成不缓存的了
        chain.doFilter(request, response);
    }
  • 没有过滤之前,响应头是这样的:

    java filter,servlet,java,开发语言

     
  • 过滤之后,响应头是这样的:

    java filter,servlet,java,开发语言

     

2.实现自动登陆

  • 实体:
 private String username ;
    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    //各种setter和getter
  • 集合模拟数据库
   public class UserDB {

        private static List<User> users = new ArrayList<>();

        static {
            users.add(new User("aaa", "123"));
            users.add(new User("bbb", "123"));
            users.add(new User("ccc", "123"));
        }

        public static List<User> getUsers() {
            return users;
        }

        public static void setUsers(List<User> users) {
            UserDB.users = users;
        }
    }
  • 开发dao
 public User find(String username, String password) {

        List<User> userList = UserDB.getUsers();

        //遍历List集合,看看有没有对应的username和password
        for (User user : userList) {
            if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
                return user;
            }
        }
        return null;
    }
  • 登陆界面
<form action="${pageContext.request.contextPath}/LoginServlet">

    用户名<input type="text" name="username">
    <br>
    密码<input type="password" name="password">
    <br>

    <input type="radio" name="time" value="10">10分钟
    <input type="radio" name="time" value="30">30分钟
    <input type="radio" name="time" value="60">1小时
    <br>

    <input type="submit" value="登陆">

</form>
  • 处理登陆的Servlet
    //得到客户端发送过来的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        UserDao userDao = new UserDao();
        User user = userDao.find(username, password);

        if (user == null) {
            request.setAttribute("message", "用户名或密码是错的!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
        }

        //如果不是为空,那么在session中保存一个属性
        request.getSession().setAttribute("user", user);
        request.setAttribute("message", "恭喜你,已经登陆了!");

        //如果想要用户关闭了浏览器,还能登陆,就必须要用到Cookie技术了
        Cookie cookie = new Cookie("autoLogin", user.getUsername() + "." + user.getPassword());

        //设置Cookie的最大声明周期为用户指定的
        cookie.setMaxAge(Integer.parseInt(request.getParameter("time")) * 60);

        //把Cookie返回给浏览器
        response.addCookie(cookie);

        //跳转到提示页面
        request.getRequestDispatcher("/message.jsp").forward(request, response);
  • 过滤器
       HttpServletResponse response = (HttpServletResponse) resp;
        HttpServletRequest request = (HttpServletRequest) req;

        //如果用户没有关闭浏览器,就不需要Cookie做拼接登陆了
        if (request.getSession().getAttribute("user") != null) {
            chain.doFilter(request, response);
            return;
        }

        //用户关闭了浏览器,session的值就获取不到了。所以要通过Cookie来自动登陆
        Cookie[] cookies = request.getCookies();
        String value = null;
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if (cookies[i].getName().equals("autoLogin")) {
                value = cookies[i].getValue();
            }
        }

        //得到Cookie的用户名和密码
        if (value != null) {

            String username = value.split("\\.")[0];
            String password = value.split("\\.")[1];

            UserDao userDao = new UserDao();
            User user = userDao.find(username, password);

            if (user != null) {
                request.getSession().setAttribute("user", user);
            }
        }

        chain.doFilter(request, response);
  • 效果:

java filter,servlet,java,开发语言文章来源地址https://www.toymoban.com/news/detail-676893.html

到了这里,关于[Java]过滤器(Filter)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 过滤器Filter

    过滤器Filter

    什么是Filter? Filter表示过滤器,是JavaWeb三大组件(Servlet、FIlter、Listener)之一。 过滤器可以把对资源的请求拦截下来,总而实现一些特殊的功能 使用过滤器后,要想访问web服务器上的资源,必须先经过过滤器,过滤器处理完毕后,才可以访问对应的资源。 过滤器一般完成

    2023年04月12日
    浏览(17)
  • 认识Filter(过滤器)

    认识Filter(过滤器)

    Filter介绍 在计算机编程中,Filter(过滤器)是一种用于对数据流进行处理的软件组件。Filter 的作用是从输入流中获取数据,对其进行处理后再将其写入输出流中。Filter 组件通常用于数据校验、数据转换、数据压缩等方面,以及对网络通信进行处理。在 Web 开发中,Filter 是

    2024年02月02日
    浏览(13)
  • 033-安全开发-JavaEE应用&SQL预编译&Filter过滤器&Listener监听器&访问控制

    033-安全开发-JavaEE应用&SQL预编译&Filter过滤器&Listener监听器&访问控制

    1、JavaEE-JDBC-SQL预编译 2、JavaEE-HTTP-Filter过滤器 3、JavaEE-对象域-Listen监听器 演示案例: ➢JavaEE-预编译-SQL ➢JavaEE-过滤器-Filter ➢JavaEE-监听器-Listen 提前编译好执行逻辑,你注入的语句不会改变原有逻辑! 预编译写法: safesql 是一个预编译的 SQL 查询语句,其中 ? 是一个占位符

    2024年02月22日
    浏览(13)
  • 布隆过滤器(Bloom Filter)

    布隆过滤器(Bloom Filter)

    通常我们会遇到很多要判断一个元素是否在某个集合中的业务场景,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间也会呈现线性增长,

    2024年02月08日
    浏览(13)
  • JavaWeb 中 Filter过滤器

    JavaWeb 中 Filter过滤器

    @ 目录 Filter过滤器 每博一文案 1. Filter 过滤器的概述 2. Filter 过滤器的编写 3. Filter 过滤器的执行过程解析 3.1 Filter 过滤结合 Servlet 的使用 4. Filter 过滤器的拦截路径: 4.1 精确匹配路径 4.2 目录匹配 4.3 前后缀名路径匹配 4.4 所有路径匹配 5. 设置 Filter 执行顺序 6. Filter 过滤器中

    2024年02月03日
    浏览(15)
  • SpringCloudGateway--过滤器(内置filter)

    SpringCloudGateway--过滤器(内置filter)

    目录 一、概览 二、内置过滤器 1、StripPrefix 2、AddRequestHeader 3、AddResponseHeader 4、DedupeResponseHeader 5、AddRequestParameter 6、CircuitBreaker 7、FallbackHeaders 8、RequestRateLimiter 9、RedirectTo 10、RemoveRequestHeader 11、RemoveResponseHeader 12、RemoveRequestParameter 13、RewritePath  14、RewriteResponseHeader  15、S

    2024年02月01日
    浏览(17)
  • PHP伪协议filter详解,php://filter协议过滤器

    PHP伪协议filter详解,php://filter协议过滤器

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 php:// 用来访问输入和输出流(I/O streams)。 输入/输出流也就是 「数据流」

    2024年02月08日
    浏览(14)
  • 结果过滤器—MVC项目中结果过滤器(Result Filter)使用

    结果过滤器—MVC项目中结果过滤器(Result Filter)使用

    结果过滤器( ResultFilter ),是对执行的Action结果进行处理的一种AOP思想,适用于任何需要直接环绕 View 或格式化处理的逻辑。结果过滤器可以 替换或更改 Action 结果 。在 IActionResult 执行的前后执行,使用它能够控制Action的执行结果,比如:格式化结果等。需要注意的是,它只

    2024年02月12日
    浏览(56)
  • SpringCloudGateway--过滤器(自定义filter)

    SpringCloudGateway--过滤器(自定义filter)

    目录 一、概览  二、全局过滤器GlobalFilter 三、通过GatewayFilter实现 四、继承AbstractGatewayFilterFactory        当使用Spring Cloud Gateway构建API网关时,可以利用Spring Cloud Gateway提供的内置过滤器(filter)来实现对请求的处理和响应的处理。过滤器可以在请求被路由之前或之后被执

    2024年02月06日
    浏览(13)
  • gateway之过滤器(Filter)详解

    gateway之过滤器(Filter)详解

    在Spring Cloud中,过滤器(Filter)是一种关键的组件,用于在微服务架构中处理和转换传入请求以及传出响应。过滤器位于服务网关或代理中,并通过拦截请求和响应流量来提供各种功能。 过滤器在请求的不同生命周期阶段执行特定的操作,例如鉴权、认证、请求转发、限流、

    2024年02月05日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包