我的GitHub: Powerveil · GitHub
我的Gitee: Powercs12 (powercs12) - Gitee.com
皮卡丘每天学Java
相关知识:Mybatis Plus、Spring Security
本质原因:我们自己将Article字段的update字段做了自动填充导致自动填充时无法获取当前用户(程序刚开始没有用户登录)。
为了代码更完善一点,我写了自动填充,但是这也导致了一个问题,在执行updateBatchById(articles)的时候,create相关字段会自动填充,看一下自动填充的具体代码。
getUserId()这个方法
看到这里大家可能就明白了,此时我们还没有登录,获取getLoginUser()就会出错,具体是jwt检验token的时候没有将当前用户信息存入存入SecurityContextHolder。其实也没必要存,因为我们做的是定时任务,不需要什么用户信息。
没有执行SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
所以Authentication没有我们想要的值。没看过源码,不知道有没有默认值(没有默认值,后面看异常出现的位置可以推测)
下图两个位置出现空指针异常(如果Authentication有默认值,1出报异常,没有默认值,2出报异常)
异常信息的下面
上图可见,1处报异常
所以上面讨论的Authentication没有默认值。
解决方案1:去掉Article部分字段的自动填充
测试结果:
解决方案2(推荐):
从根源修改:
保留自动填充,因为这里没有牵扯到用户,所以自动填充的时候要判断是否填充
public class SecurityUtils {
/**
* 获取用户
**/
public static LoginUser getLoginUser() {
if (!Objects.isNull(getAuthentication())) {
return (LoginUser) getAuthentication().getPrincipal();
}
return null;
}
/**
* 获取Authentication
*/
public static Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
public static Boolean isAdmin() {
if (!Objects.isNull(getLoginUser())) {
Long id = getLoginUser().getUser().getId();
return SystemConstants.USER_ADMIN_ID.equals(id);
}
return false;
}
public static Long getUserId() {
if (!Objects.isNull(getLoginUser())) {
return getLoginUser().getUser().getId();
}
return null;
}
测试结果:
因为刚才着急测试结果,次数多了几次。