springBoot 2.x filter -- listener -- interceptor

springboot 2.x filters

1. What is springboot 2.x filter

  • Similar to a ticket inspector, checks the tickets of tourists

2. Filters in springboot

ApplicationContextHeaderFilter
OrderedCharacterEncodingFilter
OrderedFormContentFilter
OrderedRequestContextFilter

3. Priority of filters

  • Higher values ​​are interpreted as lower priority

4. Customize the Filter to avoid the same priority as the default Filter, otherwise it will conflict

  • There are two ways to register Filter configuration
    • bean FilterRegistrationBean
    • Servlet 3.0 webFilter

5. Use the annotations of the new version of servlet 3.0 to develop custom Filters

  • Add the annotation @ServletComponentScan to the startup class to scan
  • Create a new Filter class, implements Filter, and implement the corresponding interface
  • @WebFilter marks a class as filter, which is scanned by spring
  • urlPatterns: interception rules, support regular, urlPatterns is the path to filter, filterName is the name of the filter
  • Control the method call of chain.doFilter to realize whether to release
  • No release, web application resp.sendRedirect("/index.html") or return json string

Scope of use: permission control, user login status control

5.1 Add the annotation @ServletComponentScan to the startup class

@SpringBootApplication     //标记此类为springboot 应用
@ServletComponentScan
public class MavenDemoApplication {
    
    
	public static void main(String[] args) {
    
    
		SpringApplication.run(MavenDemoApplication.class, args);
	}
}

5.2 Create a new filter package and create a Filter class in the package

insert image description here

5.3 The Filter interface is implemented in the class, and the class is marked as @WebFilter, urlPatterns is the filtered path (filters all paths under /api/v1/pri/), and filterName is the name of the filter (login filter)

insert image description here

5.4 Override 3 methods in the class implementing the interface

public void init(FilterConfig filterConfig) throws ServletException {}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}

public void destroy() {}

The above three methods are all used when the class is loaded, initialization-filtering-destroy, the filtering process occurs in the second filtering
. The code in the filtering process:

@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        System.out.println("过滤开始");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse rep = (HttpServletResponse) servletResponse;

        String token =req.getHeader("token");   //从headers中得到token
        if (StringUtils.isEmpty(token)){
    
               // 如果header里面没有token时,从请求的参数里面拿token
            token = req.getParameter("token");
        }
        if (!StringUtils.isEmpty(token)){
    
                //如果还为空,直接返回json字符串或跳转index页面
            // 判断token是否合法
            User user = UserServiceImpl.sessionMap.get(token);  //在登录时在sessionMap里存了token,通过token取出user,若为空则未登录,若不为空则显示正确
            if(user !=null){
    
    
                filterChain.doFilter(servletRequest,servletResponse);
            }else{
    
    
                JsonData jsonData = JsonData.buildError("登录失败,token无效",-2);
                String jsonStr = objectMapper.writeValueAsString(jsonData);         //json转字符
                renderJson(rep,jsonStr);
            }
        }else {
    
    
            JsonData jsonData = JsonData.buildError("登录失败,token无效",-3);
            String jsonStr = objectMapper.writeValueAsString(jsonData);    
            renderJson(rep,jsonStr);
        }
    }
    private void renderJson(HttpServletResponse response,String json){
    
    
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        try(PrintWriter writer=response.getWriter()){
    
    
            writer.print(json);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }

insert image description here

springboot listener

Listener:

Application startup listener, session listener, request listener

effect:

  • ServletContextListener application startup listener
  • HttpSessionListener session listener
  • ServletRequestListener request listener

Common listeners

ServletContextListener、HttpSessionListener、ServletRequestListener)

Code:

@WebListener
public class CustomSessionListener implements HttpSessionListener {
    
    
    @Override
    public void sessionCreated(HttpSessionEvent se) {
    
    
        System.out.println("会话监听已开启");
        //HttpSessionListener.super.sessionCreated(se);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
    
    
        System.out.println("会话监听已销毁");
        //HttpSessionListener.super.sessionDestroyed(se);
    }
}

SpringBoot2.X interceptor

1. Interceptor:

Basically similar to filter usage

2. Steps to use SpringBoot2.X interceptor:

  • 2.1 Create a class (such as: CustomWebConfigurer class) to implement the WebMvcConfigurer interface Interceptor configuration class
  • 2.2 Annotate @COnfiguration on the class
  • 2.3 Override the addInterceptors method in the class, and add multiple custom interceptors to the method
  • 2.4 Custom Interceptors
    • preHandle: Before calling a method of Controller
    • postHandle: Called after the Controller, before the view is rendered, if an
      exception occurs in the Controller, this method will not be executed
    • afterCompletion: Regardless of whether there is an exception, this afterCompletion will be called for resource
      cleanup

Interceptor configuration class code:

/**
 * 拦截器配置类
 */
@Configuration
public class CustomWebConfigurer implements WebMvcConfigurer {
    
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(getLoginInterceptor()).addPathPatterns("/api/v1/pri/**");
        //可添加多个拦截器
        registry.addInterceptor(new TwoLoginIntercepter()).addPathPatterns("/api/v1/pri/**");

        WebMvcConfigurer.super.addInterceptors(registry);
    }
    @Bean
    public LoginIntercepter getLoginInterceptor(){
    
    
        return new LoginIntercepter();
    }
}

Interceptor implementation class code:

public class LoginIntercepter implements HandlerInterceptor {
    
    
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("LoginIntercepter preHandle...");

        String token =request.getHeader("token");   //从headers中得到token
        if (StringUtils.isEmpty(token)){
    
    
            token = request.getParameter("token");
        }
        if (!StringUtils.isEmpty(token)){
    
    
            // 判断token是否合法
            User user = UserServiceImpl.sessionMap.get(token);
            if(user !=null){
    
    
                return true;
            }else{
    
    
                JsonData jsonData = JsonData.buildError("登录失败,token无效",-2);
                String jsonStr = objectMapper.writeValueAsString(jsonData);
                renderJson(response,jsonStr);
                return false;
            }
        }else {
    
    
            JsonData jsonData =JsonData.buildError("未登录",-3);
            String jsonStr = objectMapper.writeValueAsString(jsonData);
            renderJson(response,jsonStr);
            return false;
        }
        //return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    private void renderJson(HttpServletResponse response,String json){
    
    
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        try(PrintWriter writer=response.getWriter()){
    
    
            writer.print(json);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("LoginIntercepter postHandle...");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("LoginIntercepter afterCompletion...");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

Common problems with interceptors not working:

  • Whether to add @Configuration
  • Is there a problem with the interception path ** and *
  • The final path of the interceptor must be /** if it is a directory, it is /*/

The difference between Filter and Filter

  • Both Filter and Interceptor are the embodiment of AOP programming ideas, and the functions can basically be realized
  • The interceptor is more powerful, and it can do everything that Filter can do
  • Filter only works before and after Servlet, while Interceptor is deep enough before and after methods, before and after exceptions are thrown, etc.
  • The filter depends on the servlet container, that is, the web application, while the interceptor does not depend on the servlet container, so it can run in
    a variety of environments.
  • During the life cycle of the interface call, the Interceptor can be called multiple times, while the Filter can only be called once when the container is initialized
    .
  • Execution order of Filter and Interceptor Before filtering -> before intercepting -> action execution -> after intercepting -> after filtering

How to configure not to block certain paths?

registry.addInterceptor(new
LoginIntercepter()).addPathPatterns("/api/v1/pri/**")

//Configure not to intercept certain paths, such as static resources.excludePathPatterns
("/ /*.html","/ /*.js");

Guess you like

Origin blog.csdn.net/m0_49969111/article/details/118726066