【SpringBoot】SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener
=================6、SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener ============
1、深入SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战(核心知识)
简介:讲解SpringBoot里面Filter讲解和使用Servlet3.0配置自定义Filter实战
filter简单理解:人--->检票员(filter)---> 景点
1、SpringBoot启动默认加载的Filter
characterEncodingFilter
hiddenHttpMethodFilter
httpPutFormContentFilter
requestContextFilter
2、Filter优先级
Ordered.HIGHEST_PRECEDENCE
Ordered.LOWEST_PRECEDENCE
低位值意味着更高的优先级 Higher values are interpreted as lower priority
自定义Filter,避免和默认的Filter优先级一样,不然会冲突
注册Filter的bean FilterRegistrationBean
同模块里面有相关默认Filter
web->servlet->filter
3、自定义Filter
1)使用Servlet3.0的注解进行配置
2)启动类里面增加 @ServletComponentScan,进行扫描
3)新建一个Filter类,implements Filter,并实现对应的接口
4) @WebFilter 标记一个类为filter,被spring进行扫描
urlPatterns:拦截规则,支持正则
6)控制chain.doFilter的方法的调用,来实现是否通过放行
不放行,web应用resp.sendRedirect("/index.html");
场景:权限控制、用户登录(非前端后端分离场景)等
1、官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners
package net.xdclass.demo.Filter; import java.io.IOException; 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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebFilter(urlPatterns = "/api/*", filterName = "loginFilter") public class LoginFilter implements Filter{ /** * 容器加载的时候调用 */ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init loginFilter"); } /** * 请求被拦截的时候进行调用 */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("doFilter loginFilter"); HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; String username = req.getParameter("username"); if ("xdclass".equals(username)) { filterChain.doFilter(servletRequest,servletResponse); } else { resp.sendRedirect("/index.html"); return; } } /** * 容器被销毁的时候被调用 */ @Override public void destroy() { System.out.println("destroy loginFilter"); } }
2、Servlet3.0的注解自定义原生Servlet实战
讲解:使用 Servlet3.0的注解自定义原生Servlet和Listener
1、自定义原生Servlet
@WebServlet(name = "userServlet",urlPatterns = "/test/customs")
public class UserServlet extends HttpServlet{
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("custom sevlet");
resp.getWriter().flush();
resp.getWriter().close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
3、Servlet3.0的注解自定义原生Listener监听器实战
简介:监听器介绍和Servlet3.0的注解自定义原生Listener监听器实战
1、自定义Listener(常用的监听器 servletContextListener、httpSessionListener、servletRequestListener)
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
// TODO Auto-generated method stub
System.out.println("======requestDestroyed========");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("======requestInitialized========");
}
4、SpringBoot2.X自定义拦截器实战及新旧配置对比(核心知识)
简介: 讲解拦截器使用,Spingboot2.x新版本配置拦截拦截器和旧版本SpringBoot配置拦截器区别讲解
类似filter,但是不等同。
1、@Configuration
继承WebMvcConfigurationAdapter(SpringBoot2.X之前旧版本)
package net.xdclass.demo.intecpter; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; //@Configuration public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/"); super.addInterceptors(registry); } }
SpringBoot2.X 新版本配置拦截器 implements WebMvcConfigurer
package net.xdclass.demo.intecpter; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api2/*/**"); registry.addInterceptor(new TwoIntercepter()).addPathPatterns("/api2/*/**"); //.excludePathPatterns("/api2/xxx/**"); //拦截全部 /*/*/** WebMvcConfigurer.super.addInterceptors(registry); } }
2、自定义拦截器 HandlerInterceptor (分2步骤:1.新建intercept实现接口 2配置类实现接口,注解注册,添加新建的拦截器到url映射)
preHandle:调用Controller某个方法之前
postHandle:Controller之后调用,视图渲染之前,如果控制器Controller出现了异常,则不会执行此方法
afterCompletion:不管有没有异常,这个afterCompletion都会被调用,用于资源清理
package com.atguigu.springboot.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginIntercepter implements HandlerInterceptor{ /** * 进入controller方法之前 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("LoginIntercepter------->preHandle"); // String token = request.getParameter("access_token"); // // response.getWriter().print("fail"); return HandlerInterceptor.super.preHandle(request, response, handler); } /** * 调用完controller之后,视图渲染之前 */ @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); } }
3、按照注册顺序进行拦截,先注册,先被拦截
拦截器不生效常见问题:
1)是否有加@Configuration
2)拦截路径是否有问题 ** 和 *
3)拦截器最后路径一定要 “/**”, 如果是目录的话则是 /*/
Filter
是基于函数回调 doFilter(),而Interceptor则是基于AOP思想
Filter在只在Servlet前后起作用,而Interceptor够深入到方法前后、异常抛出前后等
依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。
在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。
Filter和Interceptor的执行顺序
过滤前->拦截前->action执行->拦截后->过滤后