题主在学习苍穹外卖时,添加购物车总是添加失败,就是sql语句都能顺利打印,但是插入sql不成功,通过日志发现时jwt拦截器的问题,于是在jwt上进行验证。
首先确认一点,insert操作不返回结果,其实就是因为userId=null,而数据库字段将user_id设置为NOT NULL,所以会直接插入失败。
通过debug发现,是由于ShoppingCartServiceImpl类中addShoppingCart方法的如下代码BaseContext.getCurrentId()得到的是null,所以setUserId也是null。BaseContext.getCurrentId()就是jwt拦截器的问题了,于是又转到拦截器jwt中。
shoppingCart.setUserId(BaseContext.getCurrentId());
在确定拦截器问题前,首先要确定WebMvcConfiguration类中成功配置拦截器,代码如下所示。
//注册自定义拦截器
protected void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册自定义拦截器...");
registry.addInterceptor(jwtTokenAdminInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/employee/login");
registry.addInterceptor(jwtTokenUserInterceptor)
.addPathPatterns("/user/**")
.excludePathPatterns("/user/user/login")
.excludePathPatterns("/user/shop/status");
}
然后就开始查看JwtTokenUserInterceptor拦截器,通过debug操作后发现是下面这段代码的问题。
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
在这段代码前后加入一些log日志,确定了问题,加入的日志如下
log.info("handler 实际类型 = {}", handler.getClass().getName());
log.info("handler instanceof HandlerMethod 判断结果: {}", handler instanceof HandlerMethod);
log.info("handler 的类加载器: {}", handler.getClass().getClassLoader());
log.info("HandlerMethod 的类加载器: {}", HandlerMethod.class.getClassLoader());
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
log.info("不是 HandlerMethod,放行");
return true;
}
然后输出日志就是如下,非常的自相矛盾。
日志中打印的 handler 实际类型 = org.springframework.web.method.HandlerMethod
然而紧接着输出的却是:handler instanceof HandlerMethod 判断结果: false
然后它就走进了 if (!(handler instanceof HandlerMethod)) 条件分支,执行了放行逻辑,跳过了 JWT 校验。
我问了ChatGPT,它说可能是因为类加载器不同,导致 instanceof 判断失败,于是我又加了一点验证类加载器,结果输出结果显示handler和HandlerMethod的类加载器是一样的,所以就很自我矛盾。
又问gpt,回答我如下。
至此,该问题依旧没有解决,因为我赶着学习进度。于是我把这个if语句给注释掉了,放弃判断当前拦截到的是Controller的方法还是其他资源,于是jwt拦截器成功拦截并验证,添加购物车操作也成功。
后续等我有时间了,再看看这个问题并尝试解决,或者有人遇到相同类似问题并成功解决的吗。