代码改变世界

SpringBoot 中拦截器的简介及使用方式

2020-04-26 14:36  小伍2013  阅读(1212)  评论(0编辑  收藏  举报

拦截器简介

  • 拦截器通常通过动态代理的方式来执行。
  • 拦截器的生命周期由IoC容器管理,可以通过注入等方式来获取其他Bean的实例,使用更方便。

拦截器配置使用方式

实现拦截器接口:

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

private class AuthenticationInterceptor implements HandlerInterceptor {
	// 在请求处理之前进行调用(Controller方法调用之前)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException{
    	System.out.println(request.getRequestURL());
    	User user = (User)request.getSession().getAttribute("USER");
        if(user != null){
        	return true;
        }else {
        	System.out.println("no login...");
        	// request.getRequestDispatcher("/index.html").forward(request, response);
        	response.sendRedirect(request.getContextPath()+"login.html");
        	return false;
        }
        return false;
    }
    
    // 在请求处理之后视图被渲染之前进行调用(Controller方法调用之后)
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("postHandle...");
    }

	// 在请求结束之后、也就是视图被渲染之后进行调用(主要是用于进行资源清理工作)
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion...");
    }
}

将拦截器加入到配置中:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebSecurityConfig implements WebMvcConfigurer{
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new AuthenticationInterceptor())
        		//所有路径都被拦截
        		.addPathPatterns("/**")
        		//添加不拦截的路径
        		.excludePathPatterns("/userLogin", "/css/**", "/images/**", "/js/**", "/login.html");
        registry.addInterceptor(new OtherInterceptor())
                .addPathPatterns("/**");
    }
}

备注:

由于 preHandle、postHandle、afterCompletion 是不同的方法,如果在这些方法之间使用共享变量来储存值,会存在线程安全问题。而使用过滤器实现则不存在此问题。