【项目实战】Session拦截器,校验每个请求的Session

一、Session拦截器技术概览

1.1 定义

Session拦截器是一种用于Web应用中的拦截机制,主要用于在每次HTTP请求到达控制器之前检查用户的Session状态。它的主要目的是确保用户在访问受保护的资源前已经登录或者Session仍然有效。

进一步的学习资源:

  • Spring Framework官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc
  • Baeldung上的教程:https://www.baeldung.com/spring-security-web-session-management
  • Java Code Geeks:https://www.javacodegeeks.com/2014/04/spring-mvc-interceptors.html

参考文献:

  • Spring Security in Action, Second Edition by Craig Walls
  • Java Web Development with Spring, 2nd Edition by John Carnell
  • Pro Spring MVC by Siva Reddy Guttikonda, et al.

在 Java 服务里,创建拦截器拦截所有接口请求并进行校验,可通过 Spring Boot 框架结合注解与拦截器实现,下面详细介绍具体步骤: ### 1. 创建自定义注解 自定义注解用于标记需校验的接口。例如创建一个用于登录校验的注解 `Auth`: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Auth { } ``` 此注解可用于类或方法上,标记需登录校验的接口 [^1]。 ### 2. 创建自定义拦截器 创建一个类实现 `HandlerInterceptor` 接口,重写 `preHandle` 方法来进行请求校验。例如进行登录校验拦截器: ```java import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; // 检查方法上是否有 @Auth 注解 Auth auth = handlerMethod.getMethodAnnotation(Auth.class); if (auth == null) { // 检查类上是否有 @Auth 注解 auth = handlerMethod.getBeanType().getAnnotation(Auth.class); } if (auth != null) { // 进行登录校验逻辑,例如校验 session // 这里简单示例,实际需根据业务实现 if (request.getSession().getAttribute("user") == null) { // 未登录,返回错误信息或重定向到登录页面 response.sendRedirect("/login"); return false; } } } return true; } } ``` ### 3. 注册拦截器 创建一个配置类实现 `WebMvcConfigurer` 接口,重写 `addInterceptors` 方法来注册拦截器: ```java 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 { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**"); // 拦截所有请求 } } ``` ### 其他校验场景示例 #### 账户状态校验 可创建自定义注解 `FrozenAcc` 标记需进行账户状态校验请求方法,在拦截器中执行账户状态判断: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FrozenAcc { boolean permission() default false; } ``` 拦截器中进行账户状态判断: ```java import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; public class AccountStatusInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; FrozenAcc frozenAcc = handlerMethod.getMethodAnnotation(FrozenAcc.class); if (frozenAcc != null) { // 进行账户状态判断逻辑 // 这里简单示例,实际需根据业务实现 if (accountStatusIsAbnormal()) { // 账户状态异常,抛出自定义异常 throw new CustomException("Account status is abnormal"); } } } return true; } private boolean accountStatusIsAbnormal() { // 实际业务中根据数据库或其他数据源判断账户状态 return false; } } ``` #### 接口幂等性校验 编写自定义注解和拦截器进行接口幂等性校验: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Idempotent { } ``` 拦截器: ```java import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; public class IdempotentInterceptor implements HandlerInterceptor { private RedisTemplate<String, String> redisTemplate; public IdempotentInterceptor(RedisTemplate<String, String> redisTemplate) { this.redisTemplate = redisTemplate; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Idempotent idempotent = handlerMethod.getMethodAnnotation(Idempotent.class); if (idempotent != null) { String token = request.getHeader("token"); if (token != null && redisTemplate.hasKey(token)) { if (redisTemplate.delete(token)) { return true; } else { throw new Exception("Idempotent check failed"); } } else { throw new Exception("Invalid token"); } } } return true; } } ``` #### 签名校验拦截器中进行签名校验,拦截三方应用请求接口: ```java import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; public class SignatureInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 进行签名校验逻辑 // 这里简单示例,实际需根据业务实现 if (!isSignatureValid(request)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } return true; } private boolean isSignatureValid(HttpServletRequest request) { // 实际业务中根据签名算法和密钥进行校验 return false; } } ``` ### 总结 通过自定义注解和拦截器,能够灵活控制每个接口的校验逻辑,实现对所有接口请求的拦截和校验。同时,这种方式具有灵活配置、非侵入式、层次分明、易于扩展和性能优化等特点 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

本本本添哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值