当前位置: 首页 > 工具软件 > sa-plus > 使用案例 >

Sa-Token API异步调用失败:非Web上下文!!!

茅秦斩
2023-12-01

场景:

MetaObjectHandler:mybatistPlus提供给我们的一个拓展接口,我们可以重写 insertFill updateFill 方法来对我们入库的对象的字段进行设置,比如createTime,createBy,lockVersion等这些通用字段,这些字段基本每个表都会有,每次调用新增或者修改等需要入库的方法前去设置太过于麻烦,因此在这里进行设置!

当然也可以自己封装一个方法在插入前进行设置!但是每次插入也需要调用方法,这个接口还是省去了些力气,但是本次业务开发过程中就遇到这样的问题:

当我开启异步调用的时候,进行入库操作,SessionUser sessionUser = SessionTools.tokenInfo();就发生了错误!这个是获取当前登录用户信息的方法,其中调用了Sa-Token的接口

package com.jm.component;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.jm.base.dto.SessionUser;
import com.jm.base.util.SessionTools;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

/**
 * mybatis持久化对象处理器
 *
 * @author zwf
 * @date 2022/11/02
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final String CREATE_BY = "createBy";
    private static final String CREATE_TIME = "createTime";
    private static final String UPDATE_BY = "updateBy";
    private static final String UPDATE_TIME = "updateTime";
    private static final String LOCK_VERSION = "lockVersion";

    @Override
    public void insertFill(MetaObject metaObject) {
            SessionUser sessionUser = SessionTools.tokenInfo();
            LocalDateTime now = LocalDateTime.now();
            if (metaObject.hasSetter(CREATE_BY) && metaObject.getValue(CREATE_BY) == null) {
                metaObject.setValue(CREATE_BY, sessionUser.getUser().getId());
            }
            if (metaObject.hasSetter(CREATE_TIME)) {
                metaObject.setValue(CREATE_TIME, now);
            }
            if (metaObject.hasSetter(UPDATE_BY) && metaObject.getValue(UPDATE_BY) == null) {
                metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
            }
            if (metaObject.hasSetter(UPDATE_TIME)) {
                metaObject.setValue(UPDATE_TIME, now);
            }
            if (metaObject.hasSetter(LOCK_VERSION)) {
                metaObject.setValue(LOCK_VERSION, 0);
            }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
            SessionUser sessionUser = SessionTools.tokenInfo();
            if (metaObject.hasSetter(UPDATE_BY)) {
                metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
            }
            if (metaObject.hasSetter(UPDATE_TIME)) {
                metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
            }
    }
}

解决:

思路:异步调用的入库操作不使用MetaObjectHandler来设置这些字段,再调用入库前手动设置!但是只要是入库操作都会走这个类,所以我加了相关判断!

package com.jm.component;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.jm.base.dto.SessionUser;
import com.jm.base.option.meta.Flag;
import com.jm.base.util.SessionTools;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

/**
 * mybatis持久化对象处理器
 *
 * @author zwf
 * @date 2022/11/02
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final String CREATE_BY = "createBy";
    private static final String CREATE_TIME = "createTime";
    private static final String UPDATE_BY = "updateBy";
    private static final String UPDATE_TIME = "updateTime";
    private static final String LOCK_VERSION = "lockVersion";
    private static final String IS_ASYNC_FLAG = "isAsyncFlag";

    @Override
    public void insertFill(MetaObject metaObject) {
        Flag flag = Flag.F;
        if(metaObject.hasSetter(IS_ASYNC_FLAG)){
            flag = (Flag) metaObject.getValue(IS_ASYNC_FLAG);
        }
        if(null != flag && Flag.F.equalCode(flag.getCode())){
            SessionUser sessionUser = SessionTools.tokenInfoNotNull();
            LocalDateTime now = LocalDateTime.now();
            if (metaObject.hasSetter(CREATE_BY) && metaObject.getValue(CREATE_BY) == null) {
                metaObject.setValue(CREATE_BY, sessionUser.getUser().getId());
            }
            if (metaObject.hasSetter(CREATE_TIME)) {
                metaObject.setValue(CREATE_TIME, now);
            }
            if (metaObject.hasSetter(UPDATE_BY) && metaObject.getValue(UPDATE_BY) == null) {
                metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
            }
            if (metaObject.hasSetter(UPDATE_TIME)) {
                metaObject.setValue(UPDATE_TIME, now);
            }
            if (metaObject.hasSetter(LOCK_VERSION)) {
                metaObject.setValue(LOCK_VERSION, 0);
            }
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Flag flag = Flag.F;
        if(metaObject.hasSetter(IS_ASYNC_FLAG)){
            flag = (Flag) metaObject.getValue(IS_ASYNC_FLAG);
        }
        if(null != flag && Flag.F.equalCode(flag.getCode())){
            SessionUser sessionUser = SessionTools.tokenInfoNotNull();
            if (metaObject.hasSetter(UPDATE_BY)) {
                metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
            }
            if (metaObject.hasSetter(UPDATE_TIME)) {
                metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
            }
        }
    }
}
package com.jm.base.option.meta;

import com.baomidou.mybatisplus.annotation.EnumValue;
import com.jm.base.option.KV;

/**
 * @author zwf
 * @date 2022/10/13
 */

public enum Flag implements KV {
    /**
     * 是否标记
     */
    T("1", "是"),
    F("0", "否");

    @EnumValue
    private final String code;
    private final String msg;

    Flag(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public String getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }

    @Override
    public String getEnumName() {
        return null;
    }
}

1、我再会进行异步入库的对象新加了属性isAsyncFlag ,当代码走到MyMetaObjectHandler类中时,判断这个对象是否具备该字段,如果有则不需要该类处理createBy这些字段,就不会调用到Sa-Token的API。

2、入库前设置相关属性:

/**
 * 异步开启之前调用satoken的API获取用户信息然后作为参数进入异步
 *
 * @param param 业务参数
 * @param user 当前登录用户信息
 */
asynManager.doQueryMsg(param, SessionTools.tokenInfo().getUser());


/**
 * 为异步新增的对象设置当前用户信息,异步操作标记:解决异步无法获取saToken信息问题
 *
 * @param t 需要设置的对象
 * @param id 当前用户id
 * @param time 当前时间
 * @param <T> 
 */
private <T extends MetaEntity> void setUserInfoAndFlag(T t, Long id, LocalDateTime time){
    t.setCreateBy(id);
    t.setCreateTime(time);
    t.setUpdateBy(id);
    t.setUpdateTime(time);
    ReflectTools.setFieldValue(t, "isAsyncFlag", Flag.T);
}

// 使用
setUserInfoAndFlag(teacher, user.getId(), LocalDateTime.now());
teacherMapper.updateById(teacher);

 类似资料: