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


    场景:

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

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

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

    1. package com.jm.component;
    2. import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    3. import com.jm.base.dto.SessionUser;
    4. import com.jm.base.util.SessionTools;
    5. import org.apache.ibatis.reflection.MetaObject;
    6. import org.springframework.stereotype.Component;
    7. import java.time.LocalDateTime;
    8. /**
    9. * mybatis持久化对象处理器
    10. *
    11. * @author zwf
    12. * @date 2022/11/02
    13. */
    14. @Component
    15. public class MyMetaObjectHandler implements MetaObjectHandler {
    16. private static final String CREATE_BY = "createBy";
    17. private static final String CREATE_TIME = "createTime";
    18. private static final String UPDATE_BY = "updateBy";
    19. private static final String UPDATE_TIME = "updateTime";
    20. private static final String LOCK_VERSION = "lockVersion";
    21. @Override
    22. public void insertFill(MetaObject metaObject) {
    23. SessionUser sessionUser = SessionTools.tokenInfo();
    24. LocalDateTime now = LocalDateTime.now();
    25. if (metaObject.hasSetter(CREATE_BY) && metaObject.getValue(CREATE_BY) == null) {
    26. metaObject.setValue(CREATE_BY, sessionUser.getUser().getId());
    27. }
    28. if (metaObject.hasSetter(CREATE_TIME)) {
    29. metaObject.setValue(CREATE_TIME, now);
    30. }
    31. if (metaObject.hasSetter(UPDATE_BY) && metaObject.getValue(UPDATE_BY) == null) {
    32. metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
    33. }
    34. if (metaObject.hasSetter(UPDATE_TIME)) {
    35. metaObject.setValue(UPDATE_TIME, now);
    36. }
    37. if (metaObject.hasSetter(LOCK_VERSION)) {
    38. metaObject.setValue(LOCK_VERSION, 0);
    39. }
    40. }
    41. @Override
    42. public void updateFill(MetaObject metaObject) {
    43. SessionUser sessionUser = SessionTools.tokenInfo();
    44. if (metaObject.hasSetter(UPDATE_BY)) {
    45. metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
    46. }
    47. if (metaObject.hasSetter(UPDATE_TIME)) {
    48. metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
    49. }
    50. }
    51. }

    解决:

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

    1. package com.jm.component;
    2. import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    3. import com.jm.base.dto.SessionUser;
    4. import com.jm.base.option.meta.Flag;
    5. import com.jm.base.util.SessionTools;
    6. import org.apache.ibatis.reflection.MetaObject;
    7. import org.springframework.stereotype.Component;
    8. import java.time.LocalDateTime;
    9. /**
    10. * mybatis持久化对象处理器
    11. *
    12. * @author zwf
    13. * @date 2022/11/02
    14. */
    15. @Component
    16. public class MyMetaObjectHandler implements MetaObjectHandler {
    17. private static final String CREATE_BY = "createBy";
    18. private static final String CREATE_TIME = "createTime";
    19. private static final String UPDATE_BY = "updateBy";
    20. private static final String UPDATE_TIME = "updateTime";
    21. private static final String LOCK_VERSION = "lockVersion";
    22. private static final String IS_ASYNC_FLAG = "isAsyncFlag";
    23. @Override
    24. public void insertFill(MetaObject metaObject) {
    25. Flag flag = Flag.F;
    26. if(metaObject.hasSetter(IS_ASYNC_FLAG)){
    27. flag = (Flag) metaObject.getValue(IS_ASYNC_FLAG);
    28. }
    29. if(null != flag && Flag.F.equalCode(flag.getCode())){
    30. SessionUser sessionUser = SessionTools.tokenInfoNotNull();
    31. LocalDateTime now = LocalDateTime.now();
    32. if (metaObject.hasSetter(CREATE_BY) && metaObject.getValue(CREATE_BY) == null) {
    33. metaObject.setValue(CREATE_BY, sessionUser.getUser().getId());
    34. }
    35. if (metaObject.hasSetter(CREATE_TIME)) {
    36. metaObject.setValue(CREATE_TIME, now);
    37. }
    38. if (metaObject.hasSetter(UPDATE_BY) && metaObject.getValue(UPDATE_BY) == null) {
    39. metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
    40. }
    41. if (metaObject.hasSetter(UPDATE_TIME)) {
    42. metaObject.setValue(UPDATE_TIME, now);
    43. }
    44. if (metaObject.hasSetter(LOCK_VERSION)) {
    45. metaObject.setValue(LOCK_VERSION, 0);
    46. }
    47. }
    48. }
    49. @Override
    50. public void updateFill(MetaObject metaObject) {
    51. Flag flag = Flag.F;
    52. if(metaObject.hasSetter(IS_ASYNC_FLAG)){
    53. flag = (Flag) metaObject.getValue(IS_ASYNC_FLAG);
    54. }
    55. if(null != flag && Flag.F.equalCode(flag.getCode())){
    56. SessionUser sessionUser = SessionTools.tokenInfoNotNull();
    57. if (metaObject.hasSetter(UPDATE_BY)) {
    58. metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
    59. }
    60. if (metaObject.hasSetter(UPDATE_TIME)) {
    61. metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
    62. }
    63. }
    64. }
    65. }
    1. package com.jm.base.option.meta;
    2. import com.baomidou.mybatisplus.annotation.EnumValue;
    3. import com.jm.base.option.KV;
    4. /**
    5. * @author zwf
    6. * @date 2022/10/13
    7. */
    8. public enum Flag implements KV {
    9. /**
    10. * 是否标记
    11. */
    12. T("1", "是"),
    13. F("0", "否");
    14. @EnumValue
    15. private final String code;
    16. private final String msg;
    17. Flag(String code, String msg) {
    18. this.code = code;
    19. this.msg = msg;
    20. }
    21. @Override
    22. public String getCode() {
    23. return this.code;
    24. }
    25. @Override
    26. public String getMsg() {
    27. return this.msg;
    28. }
    29. @Override
    30. public String getEnumName() {
    31. return null;
    32. }
    33. }

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

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

    1. /**
    2. * 异步开启之前调用satoken的API获取用户信息然后作为参数进入异步
    3. *
    4. * @param param 业务参数
    5. * @param user 当前登录用户信息
    6. */
    7. asynManager.doQueryMsg(param, SessionTools.tokenInfo().getUser());
    8. /**
    9. * 为异步新增的对象设置当前用户信息,异步操作标记:解决异步无法获取saToken信息问题
    10. *
    11. * @param t 需要设置的对象
    12. * @param id 当前用户id
    13. * @param time 当前时间
    14. * @param
    15. */
    16. private extends MetaEntity> void setUserInfoAndFlag(T t, Long id, LocalDateTime time){
    17. t.setCreateBy(id);
    18. t.setCreateTime(time);
    19. t.setUpdateBy(id);
    20. t.setUpdateTime(time);
    21. ReflectTools.setFieldValue(t, "isAsyncFlag", Flag.T);
    22. }
    23. // 使用
    24. setUserInfoAndFlag(teacher, user.getId(), LocalDateTime.now());
    25. teacherMapper.updateById(teacher);

  • 相关阅读:
    Python中什么是多态,Python多态及用法详解
    Python——ASCII编码与Unicode(UTF-8,UTF-16 和 UTF-32)编码
    动态数组【python】
    Kendo UI Grid 使用总结
    Spring Aop 源码 (三) (执行过程)
    【ArcGIS微课1000例】0056:将单波段栅格背景设置为无数据NoData的方法
    学生为什么要在CSDN写博客?
    安防监控/视频汇聚平台EasyCVR云端录像不展示是什么原因?该如何解决?
    ATFX汇市:美元指数跌破关键支撑,黄金触及2000关口后回落
    Nacos——Distro一致性协议
  • 原文地址:https://blog.csdn.net/weixin_49789131/article/details/128001037