栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

过滤器 拦截器(过滤器与监听器)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

过滤器 拦截器(过滤器与监听器)

sevlet中本身存在很多自带的过滤器

使用sevlet3.0开发自定义注解:

1、需要在启动类里面加上@ServletConponetScan

2、新建一个Filter类,并implements Filter,并实现对应的接口

3、@Webfilter标记一个类为filter,并被spring扫描

4、urlPatterns:定义拦截规则

5、控制chain、dofilter的方法的调用

一般用在权限控制、登录校验扥场景中

@WebFilter(urlPatterns = "/api/v1/login
    @Override
    public void destroy() {

        // TODO
        Filter.super.destroy();
    }
}

分布式应用是将token存在redis里面;

注解原生sevlet:

@WebServlet(name = "userServlet",urlPatterns = "/api/vi/test/servlet")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("test sevlet");
        writer.flush();
        writer.close();

    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

监听器:

ServletContextListener 应用启动监听   使用的最多的HttpSessionLisener 会话监听ServletRequestListener 请求监听

对不同类型的监听器,就是继承不同的接口

@WebListener // 表名这个类是一个监听器
public class ApplicationLister implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("启动的时候调用的方法");
    }

    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("销毁时调用的方法,也就是关闭项目的时候");
    }
}
@WebListener // 表名这个类是一个监听器
public class ApplicationLister implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSessionListener.super.sessionCreated(se);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSessionListener.super.sessionDestroyed(se);
    }
}

拦截器的定义与使用:

拦截器不生效的常见问题:

- 是否有加@Configuration
- 拦截路径是否有问题**和*
- 拦截器最后的路径一定要 

自定义拦截器 HandlerInterceptor

preHandle:调用Controller方法之前postHandle:Controller调用,视图渲染之前,如果之后控制器出现异常,则不会执行afterCompletion:不管有没有异常,这个afterCompletion都会被调用,资源回收​​​​

Filter 和 Interceptor 是 AOP 编程思想的基本功能,可以实现拦截功能更强大,过滤器可以做一些事情,它可以做一些事情

过滤器只在 Servlet 前面存在,而拦截器可以到达方法前后、异常抛出前后等

filter于Servlet容器即web应用中依赖,而Interceptor不依赖于Servlet容器所以可以运行在各种环境中。

在接口调用的生命周期中,拦截器可以被多次调用,而过滤器只能在应用初始化时首次调用。
	
过滤器和拦截器的执行顺序
 	
过滤前->拦截前->动作执行->拦截后->过滤后

1、定义拦截策略

package net.xclass.intercepter;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import net.xclass.enums.BizCodeEnum;
import net.xclass.model.LoginUser;
import net.xclass.util.CommonUtil;
import net.xclass.util.JWTUtil;
import net.xclass.util.JsonData;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    
    public static ThreadLocal threadLocal = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取token
        String accessToken = request.getHeader("token");

        // 有些情况下url不能通过head进行传递,而是通过url进行传递
        if(accessToken == null){
           accessToken =  request.getParameter("token");
        }

        if(StringUtils.isNotBlank(accessToken)){
            // 不为空
            Claims claims = JWTUtil.checkJWT(accessToken);
            if(claims== null){
                // 未登录,响应结果给前端
                CommonUtil.sendJsonMessage(response, JsonData.buildResult(BizCodeEnum.ACCOUNT_UNLOGIN));
                return false;
            }

            // 已经登录的时候
            long userId =  Long.valueOf(claims.get("id").toString());
            String headImg = (String)claims.get("head_img");
            String name = (String)claims.get("name");
            String mail = (String)claims.get("mail");

//            LoginUser loginUser = new LoginUser();
//            loginUser.setHeadImg(headImg);
//            loginUser.setId(userId);
//            loginUser.setMail(mail);
//            loginUser.setName(name);

            LoginUser loginUser = LoginUser.builder()
                    .headImg(headImg).name(name).id(userId).mail(mail).build();

            
            // 通过attribute传递用户信息
           // request.setAttribute("loginUser",loginUser);
            // 通过threadlocal传递用户信息 TODO
            threadLocal.set(loginUser);

            return true;
        }

        CommonUtil.sendJsonMessage(response,JsonData.buildResult(BizCodeEnum.ACCOUNT_UNLOGIN));
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);

        threadLocal.remove();  // 完成后需要移除
    }
}

2、添加拦截路径


@Configuration
@Slf4j
public class IntercepterConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new LoginInterceptor()) // 传入的参数是拦截器即拦截策略
                .addPathPatterns("/api/coupon**")
                // 排除不拦截的路径
                .excludePathPatterns("/api/couponnew_user_coupon");
    }

}

在执行的时候,如果访问的url在拦截策略里面,就会去执行prehandle里面的内容,如果返回true,继续往下执行,如果返回的是false,不能往下执行; 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/773177.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号