在这里插入图片描述

拦截器与过滤器区别

Filter:(实现 javax.servlet.Filter 接口)

  1. 属于Servlet 容器(tomcat容器创建)
  2. 请求到达 Servlet 之前就处理,可以修改request
  3. 只能作用web程序
过滤器使用场景:

过滤敏感词汇(防止sql注入)
设置字符编码
URL级别的权限访问控制
压缩响应信息

Interceptor:(实现 org.springframework.web.servlet.HandlerInterceptor 接口)

  1. 属于Spring容器,可以通过注入到IoC容器来管理
  2. 拦截器通常通过动态代理的方式来执行
  3. 不仅可以作用web程序,也可以作用Application程序
拦截器应用场景:

登录验证,判断用户是否登录。
权限验证,判断用户是否有权限访问资源,如校验token
日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
处理cookie、本地化、国际化、主题等。
性能监控,监控请求处理时长等。
通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)

在这里插入图片描述


SpringBoot中配置拦截器

一、实现springframework的HandlerInterceptor 接口创建一个拦截器

1、Object handler:被拦截的Controller
2、ModelAndView modelAndView:Controller返回的结果
3、Exception ex:程序中发生的异常

public class LoginInterceptor implements HandlerInterceptor {
    //目标Controller方法执行之前
    true表示放行
    false表示拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("loginUser");
        if (user != null) {
        	用于日志记录
            log.info(user.getUsername()+new Date()+"请求路径:"+request.getRequestURI());
            return true;
        }
        response.sendRedirect("/");
        return false;//若被拦截则后面两个方法都不会执行
    }

    //目标Controller方法执行之后返回响应结果过程中
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        ......
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        资源回收......
    }
}

若被preHandle拦截,则后面两个方法都不会执行:
在这里插入图片描述

二、配置类中扩展WebMvcConfigurer

扩展WebMvcConfigurer添加自己的拦截器:

/**
 * 对SpringBoot的WebMvcConfigurer进行扩展
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 注册自定义拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/","/login.html","/phone","/phoneCode","/registration.html","/error/**","/css/**","/fonts/**","/images/**","/js/**","/favicon.ico");
    }
}

SpringBoot中配置web三大组件

和原生Spring配置一样,只是注释代替了xml

首先在配置文件中设置三大组件扫描路径:

@SpringBootConfiguration
@ServletComponentScan(basePackages = {"com.neuq.admin.filter","com.neuq.admin.listener","com.neuq.admin.servlet"})
public class SpringBootConfig {

    @Bean
    public WebMvcConfigurer getWebMvcConfigurer(){
        return new WebMvcConfigurer() {
            //重写各种方法进行自定义......
        };
    }

}

一、SpringBoot中配置Servlet

注意:访问注入的Servlet不会经过Spring的拦截器

@WebServlet(name = "MyServlet",urlPatterns = "/myServlet")
public class MyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("myServlet");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("myServlet");
    }
}

二、SpringBoot中配置过滤器

@WebFilter(filterName = "LoginFilter",urlPatterns = {"/form/*","/table/*","/index.html"})
public class LoginFilter implements Filter {

	/init(): 初始化Filter 实例,Filter 的生命周期与 Servlet 是相同的,
	/也就是当 Web 容器(tomcat)启动时,
	/调用 init() 方法初始化实例,Filter只会初始化一次。
	/需要设置初始化参数的时候,可以写到init()方法中。
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

	/doFilter(): 业务处理,拦截要执行的请求,对请求和响应进行处理,一般需要处理的业务操作都在这个方法中实现
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        HttpSession session = req.getSession();
        /检查是否登录
        if(session.getAttribute("loginUser")==null){
            res.sendRedirect("/");
        }else {
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }

	/destroy() : 销毁实例,关闭容器时调用 destroy() 销毁 Filter 的实例。
    @Override
    public void destroy() {

    }
}

三、SpringBoot中配置过滤器监听器

使用场景: 主要用来监听对象的创建与销毁的发生,

  1. session 的创建销毁(当前登录用户)
  2. request 的创建销毁(请求)
  3. ServletContext 创建销毁 (项目的开启与关闭)
@WebListener
public class OnlineListener implements ServletContextListener,
        HttpSessionListener, HttpSessionAttributeListener {

    // Public constructor is required by servlet spec
    public OnlineListener() {}

    // -------------------------------------------------------
    // ServletContextListener implementation
    // -------------------------------------------------------
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("项目开启");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("项目销毁");
    }

    // -------------------------------------------------------
    // HttpSessionListener implementation
    // -------------------------------------------------------
    public static int online = 0;
    
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("session被创建");
        online++;
        System.out.println("在线人数:"+online);
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("session被销毁");
        online--;
    }

    // -------------------------------------------------------
    // HttpSessionAttributeListener implementation
    // -------------------------------------------------------

    public void attributeAdded(HttpSessionBindingEvent sbe) {}

    public void attributeRemoved(HttpSessionBindingEvent sbe) {}

    public void attributeReplaced(HttpSessionBindingEvent sbe) {}
}

方法二:

不使用注解,在配置文件中注入原生组件:【验证码Servlet就需要这样注入!!

    /**
     * 原生Servlet组件注入
     * @return
     */
    @Bean
    public ServletRegistrationBean servletRegister(){
        ServletRegistrationBean<HttpServlet> srBean = new ServletRegistrationBean<>();
        srBean.setServlet(new MyServlet());
        List<String> url = new ArrayList<>();
        url.add("/myServlet");
        srBean.setUrlMappings(url);
        System.out.println("原生servlet:"+srBean);
        return srBean;
    }

    /**
     * 原生Filter组件注入
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegister(){
        FilterRegistrationBean<Filter> ftBean = new FilterRegistrationBean<>();
        ftBean.setFilter(new LoginFilter());
        List<String> url = new ArrayList<>();
        url.add("/form/*");
        url.add("/table/*");
        url.add("/index.html");
        ftBean.setUrlPatterns(url);
        System.out.println("原生Filter:"+ftBean);
        return ftBean;
    }

    /**
     * 原生Listener组件注入
     * @return
     */
    @Bean
    public ServletListenerRegistrationBean servletListenerRegister(){
        ServletListenerRegistrationBean<EventListener> ltBean = new ServletListenerRegistrationBean<>();
        ltBean.setListener(new OnlineListener());
        System.out.println("原生Listener:"+ltBean);
        return ltBean;
    }
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐