苍穹外卖添加购物车不成功,UserId=null

题主在学习苍穹外卖时,添加购物车总是添加失败,就是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拦截器成功拦截并验证,添加购物车操作也成功。

后续等我有时间了,再看看这个问题并尝试解决,或者有人遇到相同类似问题并成功解决的吗。

### 苍穹外卖应用中 `userid` 为空的解决方案 在处理苍穹外卖应用中的 `userid` 为空问题时,可以采取多种措施来确保用户身份的有效性和一致性。以下是详细的解决方案: #### 1. 用户登录状态验证 确保每次请求都携带有效的用户凭证(如 token)。通过中间件或拦截器,在每个涉及用户的接口前进行登录状态校验[^1]。 ```java // 中间件伪代码示例 public class AuthMiddleware { public void handle(Request request, Response response) throws Exception { String token = request.getHeader("Authorization"); if (token == null || !isValidToken(token)) { throw new UnauthorizedException("Invalid or missing token."); } Long userId = getUserIdFromToken(token); BaseContext.setCurrentId(userId); // 设置当前用户ID } private boolean isValidToken(String token) { /* 验证逻辑 */ } private Long getUserIdFromToken(String token) { /* 获取用户ID逻辑 */ } } ``` #### 2. 数据库默认值设置 对于新注册用户,默认为其分配唯一的 `userid` 并保存至数据库表中。这可以通过 SQL 的自增字段或者 UUID 来实现[^3]。 ```sql CREATE TABLE employees ( id BIGINT AUTO_INCREMENT PRIMARY KEY, create_user BIGINT NOT NULL DEFAULT '0', update_user BIGINT NOT NULL DEFAULT '0' ); ``` #### 3. 前端页面初始化检查 前端加载完成后立即调用 API 接口获取当前登录用户的 ID,并将其存储于本地缓存(如 localStorage 或 sessionStorage)以便后续使用[^2]。 ```javascript async function initUserId() { try { const res = await fetch('/api/user'); const data = await res.json(); window.localStorage.setItem('userId', data.userId); } catch (error) { console.error(error); } } initUserId(); // 页面加载完成即执行此函数 ``` #### 4. 后台服务层强制赋值 如果业务场景允许,在后台的服务层对某些特定的操作显式指定 `createUser` 和 `updateUser` 字段的值为当前上下文中的用户 ID。 ```java @Service public class EmployeeServiceImpl implements IEmployeeService { @Autowired private BaseContext baseContext; @Override public void saveOrUpdate(Employee employee) { employee.setCreateUser(baseContext.getCurrentId()); employee.setUpdateUser(baseContext.getCurrentId()); // 继续其他业务逻辑... } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值