学习的旅程,就像蜗牛爬山,一点点的往上爬,一点点的欣赏旅途的风景
springboot实现拦截的三种方式
- 第一:过滤器(Filter) servlet的技术
- 第二:拦截器(Interceptor) springmvc的技术(HandlerInterceptor)
- 第三:切片(Aspect) springAop切面技术
springboot拦截器注册原理:
- 第一种:springboot启动扫描到Filter后将其注册进tomcat(tomcat是由springboot底层创建的,可以注入)
- 第二种:springboot拦截链注册
- 1:什么是拦截链:springboot的WebMvcConfigurer接口提供了添加注册类的接口方法addResourceHandlers
- 2:什么是注册类:比如我们自定义的拦截器(HandlerInterceptor)
- 3:注册原理:springboot启动扫描WebMvcConfigurer实现类,将拦截链上存放的拦截器注入到springmvc的拦截列表内
第一种方式实现:
- 第一步:springboot启动类上添加@ServletComponentScan 注解,开启拦截器扫描
- 第二步:编写拦截类并用注解:@WebFilter(filterName = “myFilter”, urlPatterns = “/*”)标识
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* 使用注解标注过滤器
* @WebFilter将一个实现了javax.servlet.Filter接口的类定义为过滤器
* 属性filterName声明过滤器的名称,可选
* 属性urlPatterns指定要过滤的URL模式,也可使用属性value来声明.(指定要过滤的URL模式是必选属性)
*/
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("过滤器初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("执行过滤操作");
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("过滤器销毁");
}
}
第二种方式实现:
- 第一步:创建拦截类实现拦截接口HandlerInterceptor
import com.xxx.common.exception.FastRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestFilter extends HandlerInterceptorAdapter {
private final Logger logger = LoggerFactory.getLogger(TestFilter.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("request请求地址path[{}] uri[{}]", request.getServletPath(),request.getRequestURI());
//request.getHeader(String) 从请求头中获取数据
//从请求头中获取用户token(登陆凭证根据业务而定)
Long userId= getUserId(request.getHeader("H-User-Token"));
if (userId != null && checkAuth(userId,request.getRequestURI())){
return true;
}
//这里的异常是我自定义的异常,系统抛出异常后框架捕获异常然后转为统一的格式返回给前端, 其实这里也可以返回false
throw new FastRuntimeException(20001,"No access");
}
/**
* 根据token获取用户ID
* @param userToken
* @return
*/
private Long getUserId(String userToken){
Long userId = null;
return userId;
}
/**
* 校验用户访问权限
* @param userId
* @param requestURI
* @return
*/
private boolean checkAuth(Long userId,String requestURI){
return true;
}
@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 {}
}
- 第二步:加入springboot拦截链
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 可添加多个
registry.addInterceptor(new TestFilter()).addPathPatterns("/**");//【加入拦截链,并标识拦截路径】
}
}