Springboot实现拦截器功能
preHandle: 预先处理,在目标的controller方法执行之前,进行处理
postHandle: 在目标的controller方法执行之后,到达指定页面之前进行处理
afterCompletion: 在页面渲染之后进行处理
方法
1.Springboot通过实现HandlerInterceptor接口实现拦截器
2.通过WebMvcConfigurer实现一个配置类,再通过@Configuration 注解注入到容器
3.指定拦截规则
以用户登录为案例,若用户没有登录session里面就没有用户的数据,就会转到首页登录页面
在正确登录之后,就将reglister保存到session中,再次访问页面的时候,登录拦截器就可以找到这个reglister对象,就不需要再次拦截到登录界面了.
注意:拦截器 \ 会拦截一切资源,包括静态资源,需要将静态资源放行
SpringBoot使用过滤器Filter
SpringBoot中使用过滤器Filter有两种方式
方式一: 通过注解方式实现
方式二:通过 Spring Boot 的配置类实现
方式一: 通过注解方式实现
首先先写一个过滤器Filter,在类的上方使用 @WebFilter 注解来创建Filter即可
1 | //过滤器 |
在SpringBoot项目的入口类上方使用注解 @ServletComponentScan 扫描filter包中的注解
1 | ; |
方式二:通过 Spring Boot 的配置类实现
首先先写一个过滤器Filter,不使用注解
1 | //过滤器 |
再写一个配置类
1 | //定义此类为配置类 |
最后写一个controller类
1 |
|
过滤器和拦截器的区别
- 过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
- 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet
api ,不需要依赖spring。 - 过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射
- Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
- Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。
- Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。
过滤器和拦截器非常相似,但是它们有很大的区别,最简单明了的区别就是过滤器可以修改request,而拦截器不能过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境拦截器可以调用IOC容器中的各种依赖,而过滤器不能过滤器只能在请求的前后使用,而拦截器可以详细到每个方法
JavaWeb之过滤器(filter)
filter的使用(xml配置)
1,声明一个过滤器类要实现Filter接口(CusFilter类)
public class CusFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter 初始化了");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
System.out.println("过滤请求了!!!");
//给请求放行 请求真正的资源/或者到下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("filter 销毁了");
}
}
2、配置 web.xml 文件
1 | <filter> |
过滤器(Filter)的生命周期
构造 —> 初始化 —> 过滤 —> 销毁
构造和初始化是在应用部署好后就执行的而不是第一次访问,而且是只执行一次
过滤方法是每次指定的请求发送过来的时候执行
销毁方法是应用卸载或者TOMCAT关闭的时候执行
过滤器(Filter)的拦截路径写法
1 | <filter-mapping> |
filter的使用(注解形式)
使用注解形式,就不需要再配置web.xml了
只需要在实现Filter接口的类上添加注解@WebFilter(“/*”)即可
1 |
|
多个过滤器(Filter)的执行顺序
在请求到达Servle之间是可以经过多个过滤器(Filter)的,一般情况下,建议过滤器(Filter)之间不要有关联,各自处理各自的逻辑即可。这样,我们也不需要关心执行顺序问题。
如果一定要确保执行顺序,就要对配置进行修改了,多个过滤器(Filter)的执行顺序如下
使用web.xml 配置,filter执行顺序跟的顺序有关,先声明的就会先执行
使用注解配置,filter的执行顺序跟filter名称的字母顺序有关,例如AFilter会比BFilter先执行
如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter
FilterConfig配置类
每个filter都有一个配置类
1 |
|
web.xml文件配置初始化参数
1 |
使用过滤器处理请求响应乱码案例
主要代码演示:
1 |
|
使用过滤器进行校验登陆权限案例
1.前端login.html
1 | <body> |
2.后端权限校验servlet(AuthController 类)
@WebServlet(“/auth”)
public class AuthController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
if("tom".equals(username)&&"666".equals(password)){
//验证成功后往session域中存放登录信息
HttpSession session = req.getSession();
session.setAttribute("user",new User(username,password));
resp.sendRedirect("/index.html");
}else {
resp.sendRedirect("/login.html");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
3.后端过滤器(CusFilter2类)
@WebFilter("/*")
public class CusFilter2 implements Filter {
public CusFilter2() {
System.out.println("filter2 过滤器构造了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter2 初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if(user==null){
response.sendRedirect("/login.html");
}else {
//放行,请求真正的资源/到下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
@Override
public void destroy() {
}
}
1 | <filter> |