使用 HandlerInterceptor 拦截请求

简介

HandlerInterceptor 是 Spring MVC 中的一个接口,用于在处理请求之前和之后进行一些操作。它可以用于日志记录、身份验证、权限检查等功能。

以下是 HandlerInterceptor 接口定义:

public interface HandlerInterceptor {

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

		return true;
	}

	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

}

其中包含三个方法:

  1. preHandle:在请求到达处理程序之前被调用。可以用于执行一些前置处理逻辑,例如身份验证、日志记录等。如果此方法返回true,则请求继续传递到处理程序;如果返回false,则请求处理终止。

  2. postHandle:在请求处理程序执行之后,视图渲染之前被调用。可以用于执行一些后置处理逻辑,例如修改模型数据、记录执行时间等。

  3. afterCompletion:在整个请求完成之后被调用。通常用于清理资源、记录最终日志等。可以在这里获取到处理程序的执行结果和可能的异常信息。

应用场景:用户身份验证和权限检查

背景

在一个需要用户登录才能访问的 web 应用中,通常需要在每个请求处理之前验证用户的身份。如果用户未登录,则重定向到登录页面;如果已登录,则检查用户的权限。

实现步骤

  1. 创建拦截器类

    实现HandlerInterceptor接口,重写preHandle方法进行身份验证和权限检查。

    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @Component
    public class AuthInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 检查用户是否已登录
            Object user = request.getSession().getAttribute("user");
            if (user == null) {
                // 用户未登录,重定向到登录页面
                response.sendRedirect("/login");
                return false; // 终止请求
            }
            // 用户已登录,继续处理请求
            return true;
        }
    }
    
  2. 注册拦截器

    在 Spring 的配置类中注册拦截器,并指定需要拦截的 URL 模式。

    import org.springframework.beans.factory.annotation.Autowired;
    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 WebConfig implements WebMvcConfigurer {
    
        @Autowired
        private AuthInterceptor authInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(authInterceptor)
                    .addPathPatterns("/protected/**") // 只拦截以 /protected/ 开头的请求
                    .excludePathPatterns("/login", "/register"); // 排除登录和注册请求
        }
    }
    
  3. 控制器示例

    编写一个控制器,处理受保护的资源。

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class ProtectedController {
    
        @GetMapping("/protected/resource")
        public String protectedResource() {
            return "This is a protected resource.";
        }
    }
    

测试流程

  • 未登录用户:当用户未登录并尝试访问/protected/resource时,拦截器会重定向到/login页面。
  • 已登录用户:当用户登录后,访问/protected/resource将返回"This is a protected resource."

总结

通过使用HandlerInterceptor,可以轻松实现用户身份验证和权限检查,确保只有授权用户才能访问特定资源。这种方式不仅提高了代码的可维护性,还使得身份验证逻辑与业务逻辑解耦。

参考:ChatGPT、Spring Boot 拦截器 HandlerInterceptor 的使用以及 WebMvcConfigurer 简单介绍

posted @ 2024-11-23 12:47  Higurashi-kagome  阅读(123)  评论(0)    收藏  举报