轻轻松松学习SpringBoot2:第二十四篇: Spring Boot过滤器

上篇我们讲了Spring Boot拦截器:https://blog.csdn.net/stronglyh/article/details/80980070,还有个大家容易混淆的概念,叫过滤器,有哪些区别呢

       ①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑,拦截器可以获取ioc中的service bean实现业务逻辑,拦截器可以获取ioc中的service bean实现业务逻辑,

1.过滤器和拦截器触发时机不一样:
  过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
1.过滤器和拦截器触发时间和地点不一样:
  过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
1.过滤器和拦截器触发时间和地点不一样:

  过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。



=================================实战代码==================================

举例:

定义一个过滤器,当用户访问一个页面时,判断用户是否是登录状态,如果是则跳转到对应的页面,如果不是则跳转到登录页

这个地方不使用数据库,直接硬编码,其中代码结构如下


TestFilterConfig.java

package com.example.smybatis.configurer;

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

@Configuration
public class TestFilterConfig {
    @Bean
    public FilterRegistrationBean someFilterRegistration1() {
        //新建过滤器注册类
        FilterRegistrationBean registration = new FilterRegistrationBean();
        // 添加我们写好的过滤器
        registration.setFilter( new testFilter());
        // 设置过滤器的URL模式
        registration.addUrlPatterns("/*");
        return registration;
    }

}
testC.java
package com.example.smybatis.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RestController
public class testC {
    @GetMapping(value="/test")
    public Integer test(){
        return 111;
    }

    @RequestMapping("login")
    public String login(String name,String pwd,HttpServletRequest request) {
        HttpSession session = request.getSession();

        if(name.equals("test")&&pwd.equals("test123")) {
            session.setAttribute("user",name);
            return "登录成功";
        } else {
            return "用户名或密码错误!";
        }
    }
}

testFilter.java

package com.example.smybatis.filters;

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

public class testFilter implements Filter {
//标示符:表示当前用户未登录(可根据自己项目需要改为json样式)

    String NO_LOGIN = "您还未登录";

    //不需要登录就可以访问的路径(比如:注册登录等)

    String[] includeUrls = new String[]{"/login","/register","/login.html"};

    @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(false);
        String uri = request.getRequestURI();
        System.out.println("filter url:"+uri);
        //是否需要过滤
        boolean needFilter = isNeedFilter(uri);
        if (!needFilter) { //不需要过滤直接传给下一个过滤器
            filterChain.doFilter(servletRequest, servletResponse);
        } else { //需要过滤器
            // session中包含user对象,则是登录状态
            if(session!=null&&session.getAttribute("user") != null){
                // System.out.println("user:"+session.getAttribute("user"));
                filterChain.doFilter(request, response);
            }else{
                String requestType = request.getHeader("X-Requested-With");
                //判断是否是ajax请求(因为ajax页面不跳转,所以这块需要判断一下)
                if(requestType!=null && "XMLHttpRequest".equals(requestType)){
                    response.getWriter().write(this.NO_LOGIN);
                }else{
                    //重定向到登录页(需要在static文件夹下建立此html文件)
                    response.sendRedirect(request.getContextPath()+"/login.html");
                }
                return;
            }
        }
    }

    /**
     * @Description: 是否需要过滤
     */
    public boolean isNeedFilter(String uri) {
        for (String includeUrl : includeUrls) {
            if(includeUrl.equals(uri)) {
                return false;
            }
        }
        return true;

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

ceshi.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试</title>
</head>
<body>
<h1>这是测试页面</h1>
</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<h1>这是登录页面</h1>
</body>
</html>

下面我们做几个测试

首先在浏览器输入http://localhost:1234/ceshi.html

结果跳转到了http://localhost:1234/login.html

这是因为拦截器生效了,判断用户没有登录态,则默认跳转到登录页面


接下来,我们先登录


1)登录成功了,则有登录态了

我们再访问http://localhost:1234/ceshi.html


ok,可以


2)我们再次登录,估计输错密码


3)这个时候浏览器输入http://localhost:1234/ceshi.html,我们发现又跳转到了登录页,这是因为session中没有用户的情况


====================多个过滤器排序=================

需要在配置java类中加入排序即可:registration.setOrder(1);

TestFilterConfig.java

package com.example.smybatis.configurer;

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

@Configuration
public class TestFilterConfig {    
	@Bean
    public FilterRegistrationBean someFilterRegistration1() {
        //新建过滤器注册类
        FilterRegistrationBean registration = new FilterRegistrationBean();
        // 添加我们写好的过滤器
        registration.setFilter( new SessionFilter());
        // 设置过滤器的URL模式
        registration.addUrlPatterns("/*");
        //设置过滤器顺序
        registration.setOrder(1);
        return registration;
    }
}





猜你喜欢

转载自blog.csdn.net/stronglyh/article/details/80994457