谷粒商城实战-264-商城业务-订单服务-订单登录拦截

文章目录

一,登录检测

order模块的所有请求,都需要在登录状态下进行,所以要对所有请求进行拦截,校验登录状态。

cpp 复制代码
 @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String uri = request.getRequestURI();
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        boolean match = antPathMatcher.match("/order/order/status/**", uri);
        boolean match1 = antPathMatcher.match("/payed/notify", uri);
        if (match || match1) {
            return true;
        }

        //获取登录的用户信息
        MemberResponseVo attribute = (MemberResponseVo) request.getSession().getAttribute(LOGIN_USER);

        if (attribute != null) {
            //把登录后用户的信息放在ThreadLocal里面进行保存
            loginUser.set(attribute);

            return true;
        } else {
            //未登录,返回登录页面
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.println("<script>alert('请先进行登录,再进行后续操作!');location.href='http://auth.gulimall.com/login.html'</script>");
            // session.setAttribute("msg", "请先进行登录");
            // response.sendRedirect("http://auth.gulimall.com/login.html");
            return false;
        }
    }

这段代码是Spring MVC框架中的HandlerInterceptor实现的一部分。preHandle方法在实际的控制器方法执行之前被调用。它的目的是拦截并根据用户是否已登录来控制对某些端点的访问。

下面是逻辑的分解:

  1. URI匹配:

    • 首先检查传入请求的URI是否与以下两个模式之一匹配:
      • /order/order/status/**:这个模式匹配所有以/order/order/status/开头的URL,包括任何额外的路径元素。
      • /payed/notify:这是一个精确匹配的路径/payed/notify
    • 如果URI与这两个模式中的任何一个匹配,则该方法立即返回true,允许请求无需进一步检查即可继续。这些路径似乎是配置为绕过登录要求的。
  2. 用户认证检查:

    • 接下来尝试从会话中获取登录用户的信息,通过获取名为LOGIN_USER的属性。如果用户已经登录,该属性将包含一个表示用户详细信息的MemberResponseVo对象。
    • 如果用户已验证(即attribute不为null),则将用户信息存储在一个名为loginUserThreadLocal变量中。这使得可以在整个应用程序中方便地访问用户数据,而无需显式传递。
    • 之后,该方法返回true,允许请求继续到预定的控制器方法。
  3. 处理未认证用户:

    • 如果用户未验证(即attributenull),则向客户端发送HTTP响应,内容类型设置为text/html;charset=UTF-8
    • 它向响应中写入HTML内容,其中包括JavaScript警告消息以及重定向到登录页面(http://auth.gulimall.com/login.html)。这有效地阻止了请求到达预定的端点,并将用户重定向到登录页面。
    • 最后,该方法返回false,表明请求已被处理且不应进一步继续。

二,HandlerInterceptor的原理和用法

HandlerInterceptor 是 Spring MVC 框架中的一个重要接口,用于在控制器方法执行前后进行拦截操作。通过实现 HandlerInterceptor 接口,开发者可以定义一系列钩子方法来扩展和定制请求处理流程。以下是 HandlerInterceptor 接口的主要原理和用法:

HandlerInterceptor 接口定义

HandlerInterceptor 接口定义了三个方法:

  1. preHandle: 在控制器方法执行之前被调用。
  2. postHandle: 在控制器方法执行之后,但在视图渲染之前被调用。
  3. afterCompletion: 在整个请求处理完成之后被调用,包括视图渲染。
方法签名
  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;

方法用途

  1. preHandle:

    • 这个方法在控制器方法执行前被调用。
    • 如果返回 true,则请求将继续;如果返回 false,则请求将不再继续,并且不会调用控制器方法。
    • 常用于权限验证、记录日志等操作。
  2. postHandle:

    • 这个方法在控制器方法执行后、视图渲染之前被调用。
    • 可以用来修改模型数据或做一些清理工作。
    • 例如,修改视图名称或添加模型数据。
  3. afterCompletion:

    • 这个方法在整个请求完成后被调用。
    • 可以用来释放资源或记录异常。
    • 通常用于关闭数据库连接或其他需要在请求结束后执行的操作。

使用示例

下面是一个简单的使用示例:

java 复制代码
public class MyHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 检查用户是否登录
        MemberResponseVo member = (MemberResponseVo) request.getSession().getAttribute("LOGIN_USER");
        if (member != null) {
            // 用户已登录,可以继续
            return true;
        } else {
            // 用户未登录,重定向到登录页面
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.println("<script>alert('请先进行登录,再进行后续操作!');location.href='http://auth.gulimall.com/login.html'</script>");
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 该方法在控制器方法执行后、视图渲染之前调用
        // 可以在这里做数据清理等工作
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 该方法在整个请求完成后调用
        // 可以用来释放资源或记录异常
    }
}

注册拦截器

要让拦截器生效,需要将其注册到 Spring MVC 的配置中。可以通过以下方式之一进行注册:

  1. 使用 XML 配置:

    xml 复制代码
    <mvc:interceptors>
        <bean class="com.example.MyHandlerInterceptor"/>
    </mvc:interceptors>
  2. 使用 Java 配置:

    java 复制代码
    @Configuration
    @EnableWebMvc
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MyHandlerInterceptor());
        }
    }

总结

HandlerInterceptor 提供了一个强大的机制来扩展 Spring MVC 应用程序的功能。通过实现这些方法,你可以轻松地添加诸如身份验证、日志记录、性能监控等功能,而无需修改现有的控制器代码。

相关推荐
Java追光着2 个月前
谷粒商城实战笔记-285~290-分布式事务
笔记·分布式·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-问题记录-Feign异步调用丢失请求头问题
java·笔记·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-261~262-商城业务-订单服务-页面环境搭建-SpringSession
笔记·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-275~276-商城业务-订单服务-订单确认页完成
笔记·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-259-商城业务-消息队列-可靠投递-发送端确认
笔记·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-248-商城业务-消息队列-RabbitMQ简介
笔记·分布式·rabbitmq·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-250-商城业务-消息队列-RabbitMQ安装-Docker
笔记·docker·rabbitmq·谷粒商城
Java追光着2 个月前
谷粒商城实战笔记-225~226-商城业务-认证服务-分布式session不共享不同步问题
笔记·分布式·谷粒商城
Java追光着3 个月前
谷粒商城实战笔记-230-商城业务-认证服务-页面效果完成
谷粒商城