0%

过滤器、拦截器

Springboot实现拦截器功能

preHandle: 预先处理,在目标的controller方法执行之前,进行处理

postHandle: 在目标的controller方法执行之后,到达指定页面之前进行处理

afterCompletion: 在页面渲染之后进行处理

方法

1.Springboot通过实现HandlerInterceptor接口实现拦截器

2.通过WebMvcConfigurer实现一个配置类,再通过@Configuration 注解注入到容器

3.指定拦截规则

以用户登录为案例,若用户没有登录session里面就没有用户的数据,就会转到首页登录页面

在正确登录之后,就将reglister保存到session中,再次访问页面的时候,登录拦截器就可以找到这个reglister对象,就不需要再次拦截到登录界面了.


注意:拦截器 \ 会拦截一切资源,包括静态资源,需要将静态资源放行


SpringBoot使用过滤器Filter

SpringBoot中使用过滤器Filter有两种方式

方式一: 通过注解方式实现

方式二:通过 Spring Boot 的配置类实现

方式一: 通过注解方式实现

首先先写一个过滤器Filter,在类的上方使用 @WebFilter 注解来创建Filter即可

1
2
3
4
5
6
7
8
9
//过滤器
@WebFilter(urlPatterns = "/myfilter")
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("---------您已进入过滤器----------");
filterChain.doFilter(servletRequest,servletResponse);
}
}

在SpringBoot项目的入口类上方使用注解 @ServletComponentScan 扫描filter包中的注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan(basePackages = "com.springboot.filter") //第一种方式
public class SpringbootTest14Application {

public static void main(String[] args) {
SpringApplication.run(SpringbootTest14Application.class, args);
}

}

方式二:通过 Spring Boot 的配置类实现

首先先写一个过滤器Filter,不使用注解

1
2
3
4
5
6
7
8
//过滤器
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("---------您已进入过滤器222----------");
filterChain.doFilter(servletRequest,servletResponse);
}
}

再写一个配置类

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration  //定义此类为配置类
public class FilterConfig {
@Bean
public FilterRegistrationBean myFilterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(new MyFilter());

//添加过滤路径
filterRegistrationBean.addUrlPatterns("/user/*");
return filterRegistrationBean;
}

}

最后写一个controller类

1
2
3
4
5
6
7
8
9
10
11
12
@Controller
public class MyController {
@RequestMapping("/user/detail")
public @ResponseBody String userDetail(){
return "/user/detail";
}

@RequestMapping("/center")
public @ResponseBody String center(){
return "/center";
}
}


过滤器和拦截器的区别

  1. 过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
  2. 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet
    api ,不需要依赖spring。
  3. 过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射
  4. Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
  5. Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。
  6. Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

过滤器和拦截器非常相似,但是它们有很大的区别,最简单明了的区别就是过滤器可以修改request,而拦截器不能过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境拦截器可以调用IOC容器中的各种依赖,而过滤器不能过滤器只能在请求的前后使用,而拦截器可以详细到每个方法

JavaWeb之过滤器(filter)

filter的使用(xml配置)
1,声明一个过滤器类要实现Filter接口(CusFilter类)

public class CusFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter 初始化了");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
        System.out.println("过滤请求了!!!");
        //给请求放行 请求真正的资源/或者到下一个过滤器
        filterChain.doFilter(servletRequest, servletResponse);
    }

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

2、配置 web.xml 文件

1
2
3
4
5
6
7
8
9
<filter>
<filter-name>filter</filter-name>
<filter-class>com.codeyancy.filter.CusFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

过滤器(Filter)的生命周期
构造 —> 初始化 —> 过滤 —> 销毁

构造和初始化是在应用部署好后就执行的而不是第一次访问,而且是只执行一次
过滤方法是每次指定的请求发送过来的时候执行
销毁方法是应用卸载或者TOMCAT关闭的时候执行
过滤器(Filter)的拦截路径写法

1
2
3
4
5
6
7
8
9
10
11
12
<filter-mapping>
<filter-name>filter</filter-name>
<!-- /* 表示过滤所有请求 -->
<url-pattern>/*</url-pattern>
<!--精确路径过滤-->
<url-pattern>/ajaSearch.html</url-pattern>
<!--后缀名匹配过滤-->
<url-pattern>*.html</url-pattern>
<!--目录匹配过滤-->
<url-pattern>/html/*</url-pattern>
</filter-mapping>

filter的使用(注解形式)
使用注解形式,就不需要再配置web.xml了

只需要在实现Filter接口的类上添加注解@WebFilter(“/*”)即可

1
2
@WebFilter("/*")
public class CusFilter implements Filter {

多个过滤器(Filter)的执行顺序
在请求到达Servle之间是可以经过多个过滤器(Filter)的,一般情况下,建议过滤器(Filter)之间不要有关联,各自处理各自的逻辑即可。这样,我们也不需要关心执行顺序问题。

如果一定要确保执行顺序,就要对配置进行修改了,多个过滤器(Filter)的执行顺序如下

使用web.xml 配置,filter执行顺序跟的顺序有关,先声明的就会先执行
使用注解配置,filter的执行顺序跟filter名称的字母顺序有关,例如AFilter会比BFilter先执行
如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter
FilterConfig配置类
每个filter都有一个配置类

1
2
3
4
5
6
7
8
9
10
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获取filter的初始化参数
String jdbcUrl = filterConfig.getInitParameter("jdbcUrl");
System.out.println(jdbcUrl);
// 获取上下文对象
ServletContext servletContext = filterConfig.getServletContext();
System.out.println("filter 初始化了");
}

web.xml文件配置初始化参数

1

使用过滤器处理请求响应乱码案例
主要代码演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//处理乱码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/json;charset=UTF-8");

String requestURI = request.getRequestURI();
//System.out.println("filter1 拦截了请求..." + requestURI);
filterChain.doFilter(servletRequest, servletResponse);
//System.out.println("filter1 响应了请求...");
}

使用过滤器进行校验登陆权限案例

1.前端login.html

1
2
3
4
5
6
7
<body>
<form action="/auth" method = "post">
user <input type="text" name="username"> <br>
pass <input type="password" name="password"> <br>
<input type="submit" value="登录">
</form>
</body>

2.后端权限校验servlet(AuthController 类)

@WebServlet(“/auth”)
public class AuthController extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    if("tom".equals(username)&&"666".equals(password)){
        //验证成功后往session域中存放登录信息
        HttpSession session = req.getSession();
        session.setAttribute("user",new User(username,password));

        resp.sendRedirect("/index.html");
    }else {
        resp.sendRedirect("/login.html");
    }
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
}

3.后端过滤器(CusFilter2类)

@WebFilter("/*")
public class CusFilter2 implements Filter {
    public CusFilter2() {
        System.out.println("filter2 过滤器构造了");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter2 初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

            HttpSession session = request.getSession();
            Object user = session.getAttribute("user");
            if(user==null){
                response.sendRedirect("/login.html");
            }else {
                //放行,请求真正的资源/到下一个过滤器
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    @Override
    public void destroy() {
    }
}
1
2
3
4
5
6
7
8
<filter>
<filter-name>filter</filter-name>
<filter-class>com.xufengnian.servlet</filter-class>
</filter>
<servlet-mapping>
<servlet-name>filter</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
有帮助的话可以来打赏一些或者经常来看看我哦,我在这里等你!