过滤器使用
过滤器是属于Servlet,在javax.servlet.*下面。
- 添加servlet组件扫描
@SpringBootApplication
@ServletComponentScan
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class, args);
}
}
- 创建过滤器
@WebFilter(urlPatterns = "/hello/*")
public class MyFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("配置过滤器?");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进行过滤");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("过滤完毕!");
}
@Override
public void destroy() {
System.out.println("销毁过滤器?");
}
}
在上述doFilter方法中进行拦截处理。
filterChain.doFilter(servletRequest, servletResponse);方法是将请求向下传递
- 用代码添加过滤器
我们除了可以用@WebFilter注解进行过滤器的注册,还可以使用FilterRegistrationBean类进行注册。
@WebFilter只能根据类名按照字母顺序执行
搭配@Order注解 无效
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
registration.addUrlPatterns("/hello/*");
registration.setName("MyFilter");
registration.setOrder(1);
return registration;
}
}
FilterRegistrationBean类的方式可以设置过滤器的执行顺序,数字越小,优先级越高
匹配规则
将接收到的url,去掉上下文路径,剩余的部分进行匹配
localhost:8080/sport/user
其中,/sport是context-path,所以去除上下文后是/user
Filter有4中匹配方式,4中方式不能够混合使用。
匹配规则不是正则和统配符
- 精确匹配
完全匹配路径 - 路径匹配
以/开始,必须以/*结尾 - 扩展名匹配
以*.开头 - 缺省匹配
/
过滤器疑问
- 一次请求,结果触发两次拦截
/* 和/ 会拦截静态资源的加载,所以请求过来的时候,静态资源和动态内容可能都会被拦截 - 请求异常,是否还会拦截
拦截器使用
拦截器是属于Spring MVC
创建拦截器步骤
- 实现自己的拦截器
我们一般可以实现HandlerInterceptor接口,或者继承HandlerInterceptorAdapter类来实现自己的拦截器
//@Component
public class MyInteceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("开始拦截");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("成功拦截");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
preHandle返回false,取消请求
postHandle是请求执行完毕执行
- 注册拦截器
@Configuration
public class InteceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInteceptor())
.addPathPatterns("/**").excludePathPatterns("/**/chinese");
}
}
按照我的实验结论,拦截器相对于过滤器来说,多了排除不希望处理的路径
匹配规则
? 匹配单个字符
* 匹配0个或多个字符
** 匹配0个或多个目录
执行顺序
之前碰到拦截器一直没有起作用,后来发现我在过滤的时候,没有让过滤器继续往下传,所以拦截器就没有执行