欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Shiro登录的使用以及原理---Filter过滤器原理和使用

程序员文章站 2022-07-08 16:01:57
在第一篇中进行的简单的介绍了Shiro的登录的实现https://blog.csdn.net/qq_38340127/article/details/109866392,因为主要为了后续的Spring结合Shiro,而Shiro通过Filer实现的,所以此篇主要讲Filter原理和使用。一 Filter 过滤器在web项目中Filer的主要功能就是对用户请求做预处理,接着将请求交给servlet处理并响应,然后Filter在对该相应进行后置处理。web浏览器-------->web服务器-...

在第一篇中进行的简单的介绍了Shiro的登录的实现https://blog.csdn.net/qq_38340127/article/details/109866392,因为主要为了后续的Spring结合Shiro,而Shiro通过Filer实现的,所以此篇主要讲Filter原理和使用。

一 Filter 过滤器

官方文档中的描述是:

A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both. 

(过滤器是一个对资源的请求(servlet或静态内容)或来自资源的响应执行筛选任务,或同时执行这两个任务的对象)

那么也就是说

在web项目中Filer的主要功能就是对用户请求做预处理,接着将请求交给servlet处理并响应,然后Filter在对该相应进行后置处理。

web浏览器-------->web服务器--------->Filter处理-------->servlet处理--↓

web浏览器<-------web服务器<---------Filter处理<-------------------------↓                    

1.1 Filter使用简介

Filter的官方文档:https://tomcat.apache.org/tomcat-5.5-doc/servletapi/

//该接口主要三大功能
public interface Filter {
    //初始化 实现类会继承接口中的default方法 接口也能通过default来实现方法了
    default void init(FilterConfig filterConfig) throws ServletException {
    }
    
    //执行过滤
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    //销毁
    default void destroy() {
    }
}
Method Summary
 void destroy() 
          Called by the web container to indicate to a filter that it is being taken out of service.
 void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
          The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
 void init(FilterConfig filterConfig) 
          Called by the web container to indicate to a filter that it is being placed into service.

 

FilterChain主要表示Filer链,表示编写的多个 Filter,这些 Filter组合。

1.2 Interface FilterChain

Method Summary
 void doFilter(ServletRequest request, ServletResponse response) 
          Causes the next filter in the chain to be invoked, or if the calling filter is the last filter in the chain, causes the resource at the end of the chain to be invoked.

 主要作用就是根据Filter链中对应的Filter执行过滤doFilter方法。

1.3 工作原理

执行Filter接口中的doFilter方法,该方法中有一个FilterChain对象 filterChain,然后调用filterChain的diFilter方法,继续执行下一个Filter的doFilter方法。可以理解为FilterChain链中存储了所有要执行的Filter,然后依次执行各个Filter的doFilter方法。

二 Filter开发流程

主要分为2步:

1、编写Java类实现Filter接口,并实现其主要的doFilter方法

2、注册过滤器(将过滤器信息注册到Spring),并设置其拦截的资源配置

2.1 SpringBoot添加Filter案例

2.1.1 编写(3个Filter分别对应3个注册方法)

package com.example.springboot.filters;

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

public class TestFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter1");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

package com.example.springboot.filters;

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

public class TestFilter1 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter1");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}


package com.example.springboot.filters;

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

public class TestFilter2 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter2");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

2.1.2 注册

方法一:实现Filter接口,并使用@Component注解,将TestFilter进行修改

package com.example.springboot.filters;

import org.springframework.stereotype.Component;

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

@Component
public class TestFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

确定无法确定对应的顺序,和指定对应的url 改进为@WebFilter(filterName = "TestFilter",urlPatterns = "/*")同时在SpringBootApplication上加入@ServletComponentScan,但还是无法指定顺序

方法二:@Bean的方式进行注册,极力推荐,springboot在启动后会对实现了ServletContextInitializer接口的bean,调用onStartup()方法添加对应自定义的Filter

package com.example.springboot.config;

import com.example.springboot.filters.TestFilter1;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean<TestFilter1> filter1FilterRegistrationBean() {
        FilterRegistrationBean<TestFilter1> registrationBean = new FilterRegistrationBean<>();
        TestFilter1 testFilter1 = new TestFilter1();
        registrationBean.setFilter(testFilter1);
        List<String> urls = new ArrayList<>();
        urls.add("/*");//配置过滤规则
        registrationBean.setUrlPatterns(urls);
        registrationBean.setOrder(2);// 设置拦截顺序
        return registrationBean;
    }

}

方法三:web.xml注册(springBoot中已经废弃web.xml 不推荐使用)

<?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">
        <filter>
            <filter-name>TestFilter2</filter-name>
            <filter-class>com.example.springboot.filters.TestFilter2</filter-class>
        </filter>

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

</web-app>

 

 

本文地址:https://blog.csdn.net/qq_38340127/article/details/110207312