美文网首页
拦截器Interceptor

拦截器Interceptor

作者: yuaixing003 | 来源:发表于2023-11-12 16:27 被阅读0次

    拦截器的使用步骤和过滤器类似,也分为两步:

    1.定义拦截器

    2.注册配置拦截器

    自定义拦截器:实现HandlerInterceptor接口,并重写其所有方法

    通过拦截器来完成案例当中的登录校验功能。

    @Component //当前拦截器对象由Spring创建和管理

    @Slf4j

    public class LoginCheckInterceptor implements HandlerInterceptor {

        //前置方式

        @Override

        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

            System.out.println("preHandle .... ");

            //1.获取请求url

            //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行

            //3.获取请求头中的令牌(token)

            String token = request.getHeader("token");

            log.info("从请求头中获取的令牌:{}",token);

            //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)

            if(!StringUtils.hasLength(token)){

                log.info("Token不存在");

                //创建响应结果对象

                Result responseResult = Result.error("NOT_LOGIN");

                //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)

                String json = JSONObject.toJSONString(responseResult);

                //设置响应头(告知浏览器:响应的数据类型为json、响应的数据编码表为utf-8)

                response.setContentType("application/json;charset=utf-8");

                //响应

                response.getWriter().write(json);

                return false;//不放行

            }

            //5.解析token,如果解析失败,返回错误结果(未登录)

            try {

                JwtUtils.parseJWT(token);

            }catch (Exception e){

                log.info("令牌解析失败!");

                //创建响应结果对象

                Result responseResult = Result.error("NOT_LOGIN");

                //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)

                String json = JSONObject.toJSONString(responseResult);

                //设置响应头

                response.setContentType("application/json;charset=utf-8");

                //响应

                response.getWriter().write(json);

                return false;

            }

            //6.放行

            return true;

        }

    注意:

    preHandle方法:目标资源方法执行前执行。 返回true:放行    返回false:不放行

    postHandle方法:目标资源方法执行后执行

    afterCompletion方法:视图渲染完毕后执行,最后执行

    注册配置拦截器:实现WebMvcConfigurer接口,并重写addInterceptors方法

    @Configuration

    public class WebConfig implements WebMvcConfigurer {

        //自定义的拦截器对象

        @Autowired

        private LoginCheckInterceptor loginCheckInterceptor;

        @Override

        public void addInterceptors(InterceptorRegistry registry) {

          //注册自定义拦截器对象

            registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表示拦截所有请求)

        }

    }

    拦截路径

    在注册配置拦截器的时候,我们要指定拦截器的拦截路径,通过addPathPatterns("要拦截路径")方法,就可以指定要拦截哪些资源。

    在入门程序中配置的是/**,表示拦截所有资源,而在配置拦截器时,不仅可以指定要拦截哪些资源,还可以指定不拦截哪些资源,只需要调用excludePathPatterns("不拦截路径")方法,指定哪些资源不需要拦截。

    @Configuration

    public class WebConfig implements WebMvcConfigurer {

        //拦截器对象

        @Autowired

        private LoginCheckInterceptor loginCheckInterceptor;

        @Override

        public void addInterceptors(InterceptorRegistry registry) {

            //注册自定义拦截器对象

            registry.addInterceptor(loginCheckInterceptor)

                    .addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表示拦截所有请求)

                    .excludePathPatterns("/login");//设置不拦截的请求路径

        }

    }

    在拦截器中除了可以设置/**拦截所有资源外,还有一些常见拦截路径设置:

    拦截路径含义举例

    /*一级路径能匹配/depts,/emps,/login,不能匹配 /depts/1

    /**任意级路径能匹配/depts,/depts/1,/depts/1/2

    /depts/*/depts下的一级路径能匹配/depts/1,不能匹配/depts/1/2,/depts

    /depts/**/depts下的任意级路径能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1


    过滤器和拦截器之间的区别:

    接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。

    拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。

    相关文章

      网友评论

          本文标题:拦截器Interceptor

          本文链接:https://www.haomeiwen.com/subject/lxcrwdtx.html