配置了 interceptor 不生效???

什么是 interceptor

什么是 interceptor interceptor 和 filter 的区别和联系 ?

具体可以看看这篇文章 https://cloud.tencent.com/developer/article/1839568

如何使用

1、定义

@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 执行相关逻辑
        // 返回 true 继续执行 返回 false 不继续执行
        return true;
    }
}

2、注册到 interceptors 里面

1)方式 1

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Resource
    private JwtInterceptor jwtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/api/**");
    }
}

2)方式2

@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {
	
    // 注入 bean 的方式进行使用
    @Bean
    public MappedInterceptor someMethodName() {
        return new MappedInterceptor(
                // => maps to any repository
                new String[]{"/api/**"},
                new JwtInterceptor()
        );
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 执行相关逻辑
        // 返回 true 继续执行 返回 false 不继续执行 MVC 里面的代码
        return true;
    }
}

遇到的坑

然后遇到 BUG 了!遇到了 interceptor 不生效的问题,但是我访问的确实时 /api/user/login 啊?

具体代码

@RestController
@RequestMapping("/user")
@AllArgsConstructor
public class UserController {
    
    private UserService userService;

    @PostMapping("/login")
    public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userLoginRequest == null, ErrorCode.PARAMS_ERROR);
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(loginUserVO);
    }
}

server:
  port: 8123
  servlet:
    context-path: /api

使用 IDEA 自带的 HttpClient 进行测试

###
POST http://localhost:8123/api/user/login
Content-Type: application/json

{
  "userAccount": "leikooo",
  "userPassword": "11111111"
}

解决:

直接问 AI 源码里面的核心逻辑在哪个地方,AI 说在 AbstractHandlerMapping#getHandlerExecutionChain 直接 debug

1、双击 shift 在上面输入 AbstractHandlerMapping

image-20250113115432561

2、找到 getHandlerExecutionChain 方法

image-20250113115543965

3、此时进行请求

发现 adaptedInterceptors 里面有我们自定义的 jwtInterceptor 的 patternString 证明 jwtInterceptor 注册成功

image-20250113115656486

进去具体看看 match 逻辑

image-20250113115934264

获取到的 path 是 /user/login 怪不得匹配不上 /api/** 难道是 context-path 不生效吗?

image-20250113120025233

image-20250113120323843

4、修改 controller 代码试试

@RestController
@RequestMapping("/api/user")
@AllArgsConstructor
public class UserController {
    
    private UserService userService;

    @PostMapping("/login")
    public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userLoginRequest == null, ErrorCode.PARAMS_ERROR);
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(loginUserVO);
    }
}

把 application.yml 对应的配置 context-path 给去掉

6、继续 debug 看看

发现 这个 path 有 /api 此时我们直接放行到下一个断点

image-20250113121044628

image-20250113121142631

发现可以正常走到我们自定义 interceptor 的 preHandle

image-20250113120852347

总结

因为 context-path 写的路径不会生效导致无法正常匹配路径,写 context-path:/api ,真正匹配的时候其实只有 /user/login 匹配不上咱们定义的 /api/**

解决把路径写到 controller 的 RequestMapping 中,不知道有没有大佬有其他的解决办法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值