SpringBoot2.0编写简单的过滤器和拦截器

前言

匆匆忙忙,我的5月份都已经走到了末尾。之所以很久没更新博客,是最近一直在赶项目。我一直都很喜欢狂神的那句,世上没有白走的路,因为每一步都算数。今天我跟大家分享的是如何编写过滤器和拦截器。

1. 拦截器和过滤器的根本区别

[1] 过滤器是servlet规范的,只能用于web程序中,而拦截器是在spring容器中,它不依赖servlet容器。
[2] 拦截器属于Spring中的概念,可以在拦截器中使用任何Spring中的Bean信息,而过滤器不属于Spring的概念店,所以过滤器不行。
[3] 过滤器可以拦截几乎所有的请求(包括静态资源的请求),而拦截器只能拦截Spring 中请求的处理器(不包括静态资源请求)
[4] 不管是过滤器还是拦截器都是AOP 编程思想的体现。
[5] 过滤器的执行顺序在拦截器之前

2. 过滤器的简单实现

[1] 基于SpringBoot配置 FilterRegistrationBean
[2] 使用servlet自带的注解 @WebFilter

我们这里以解决中文乱码为实例列举:
第一种方式:配置 FilterRegistrationBean
编写一个实现了Filter的类

package com.example.kcb02.component;

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

//编写一个中文乱码过滤器
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

这里的 filterChain.doFilter(servletRequest,servletResponse); 表示放行请求一定要加上

接着在FilterRegistrationBean 中对该过滤器进行注册,并把它注入到容器中

package com.example.kcb02.config;

import com.example.kcb02.component.MyFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyMvcConfig {
    //过滤器
    @Bean
    public FilterRegistrationBean traceFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        registration.addUrlPatterns("/*");
        return registration;
    } 
}

编写这样两个方法就可实现简单的过滤器,我们要实现复杂的业务只需要在doFilter()方法进行添加即可;相关的还有垃圾信息的过滤等。

第二种方式: 使用Servlet内置的注解
还是和上面一样的类,这时在MyFilter 上加上注解

package com.example.kcb02.component;

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

//编写一个中文乱码过滤器
@WebFilter(urlPatterns = "/*", filterName = "MyFilter")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }

记得这里编写网还应该在SpringBoot的main方法中添加@ServletComponentScan开启扫描Servlet 注解,这样就可以实现和上面同样的效果

//添加ServletComponentScan开启扫描Servlet注解
@ServletComponentScan
@SpringBootApplication
public class WebApplication {
  public static void main(String[] args) {
    SpringApplication.run(WebApplication.class, args);
  }
}
3. 拦截器的简单实现

[1] 编写一个实现了HandlerInterceptor的拦截器
业务需求:
这里我们对非法登录进行拦截,就是我们本来应该先通过登录才能进入主界面,但是我们不加拦截的话,我们直接输入网址也可以访问主页。
相关方法说明:
preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;(这里刚好符合我们的业务需求)
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView;(这个较少使用)
afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
实现思路:
这里先说明一下设计的相关思路:由于我登录的时候用一个session存储了用户名,只要我在这边检测到用户名不为空的话就放行请求(就是所谓的return true), 如果用户名为空的话就拦截请求(就是所谓的访问false)

package com.example.kcb02.component;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * @Auther: Gs
 * @Date: 2020/5/30
 * @Description: com.example.kcb02.component
 * @version: 1.0
 */
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        StringBuffer requestURL = request.getRequestURL();
        HttpSession session = request.getSession();
        Object username = session.getAttribute("username");
        //System.out.println("用户名为:"+username);
        //用户名不为空则放行
        if (username!=null){
            return true;
        }else{
            System.out.println("进行了拦截");
            return false;
        }
    }

    @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 {

    }
}

在SpringBoot2.0中提倡关于SpringMvc的功能扩展都去实现一个WebMvcConfigurer的类,在这个类中我们可以添加视图解析器,拦截器,格式化器等,这里我们先对添加拦截器进行简单说明。

package com.example.kcb02.config;


import com.example.kcb02.component.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.Filter;

/**
 * @Auther: Gs
 * @Date: 2020/5/4
 * @Description: com.example.kcb02.config
 * @version: 1.0
 */
//实现WebMvcConfigurer对SpringMvc的功能进行扩展
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(new MyInterceptor()).
                addPathPatterns("/courselists","/treeholes","/comments","/teachers","/students");
    }
}

这里通过addInterceptor()添加自定义的拦截器,通过addPathPatterns()添加要进行拦截的路径,可以包括多个路径。(上面所写的是我项目中进行拦截的路径)

小结

还记得在JavaWeb中最习惯的就是实现完相应的过滤器和拦截器后就在web.xml进行配置,而在SpringBoot中很多东西都喜欢以注解的形式存在,把这种在web.xml进行的配置换成配置类的形式呈现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值