StudiousTiger 2022-03-20 12:27 采纳率: 50%
浏览 203
已结题

【报NullPointerException】springboot 中 websocket 的 @OnMessage 中使用自定义的工具类,报空指针异常

问题遇到的现象和发生背景

使用websocket谢了一个简单的聊天室,当聊天用户未上线的时候,给该未上线的用户发送消息,我是想保存将未上线用户为收到的消息保存到redis中,以便该未登录用户下次登录后可以从redis中获取其未登录是本应收到的消息。因为用户发送的消息是在onMessge中发送的,我在onMessage中使用自定义的RedisUtils(通过@Component注入到了springboot中了,用的时候使用了@Autowired自动装配),总是报“NullPointerException”。

问题相关代码,请勿粘贴截图
   @Autowired
    private RedisUtils redisUtil;

    // static:因为这个类是所有用户共享的,使用 static 可以保证存储的数据不会被覆盖
    private static Map<String,ChatEndpoint> onlineUser = new ConcurrentHashMap<>();

    // 声明 websocket session对象,使得每一个用户拥有自己的独立的 session,因此我们不能使用 static
    private Session wsSession;

    // 用户取出当前用户存在 httpSession 中的信息
    private HttpSession httpSession;

    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig){
        try {
            // 给当前的 WebSocket Session 赋值
            this.wsSession = session;
            // 获取 httpSession,并存入当前的 httpSession
            this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName());

            onlineUser.put((String) httpSession.getAttribute("userId"), this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

@OnMessage
    public void onMessage(String message, Session session){
        try {
            // 将JSON 转换成 Object
            MyMessage myMessage = JSON.parseObject(message, MyMessage.class);

            // 获取要发送的消息(JSON)
            String targetSendMessage = MessageUtils.getMessage(false,(String) httpSession.getAttribute("userId"), myMessage.getMessage());

            String listID = myMessage.getToName() + httpSession.getAttribute("userId");

            // 获取当前在线的用户集合
            Set<String> onlineUsers = onlineUser.keySet();
            // 若发送消息的目标在线,直接发送消息
            if (onlineUsers.contains(myMessage.getToName())) {
                // 发送消息
                onlineUser.get(myMessage.getToName())    // 获取目标用户对应的 ChatEndpoint 类
                        .wsSession   // 目标用户对应的 ChatEndpoint 类的成员变量
                        .getBasicRemote()  //
                        .sendText(targetSendMessage);  // 发送消息(targetSendMessage  : JSON)

            } else { // 发送消息的目标不在线
                // 获取以目标用户为主角的我们的聊天记录
                List<Object> chatRecordOfText = getChatRecordOfText(listID);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private List<Object> getChatRecordOfText(String listID){
        try {
            return redisUtil.lGet(listID+"chattxt", 0, -1);
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
运行结果及报错内容

img

img

我的解答思路和尝试过的方法

1、我试过 new RedisUtils(),结果也是“空指针异常”

我想要达到的结果

能够在 OnMessage 使用自定义个 RedisUtils 访问 redis 服务器

展开全部

  • 写回答

1条回答 默认 最新

  • StudiousTiger 2022-03-20 15:01
    关注

    ###解决了,我之前不知道为什么 @Autowried会失败,最后我使用手动注入RedisUtils,成功了。

    将原本的自动注入:

    @Autowired
        private RedisUtils redisUtil
    

    改为手动注入:

    private RedisUtils redisUtil = BeanUtils.getBean(RedisUtils.class);
    

    Bean工具类:

    @Component
    public class BeanUtils implements ApplicationContextAware  {
        protected static ApplicationContext applicationContext ;
    
        @Override
        public void setApplicationContext(ApplicationContext arg0) throws BeansException {
            if (applicationContext == null) {
                applicationContext = arg0;
            }
     
        }
        /**
         * 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象
         */
        public static <T> T getBean(Class<T> clazz) {
            return applicationContext.getBean(clazz);
        }
    }
    

    完美解决

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 3月27日
  • 已采纳回答 3月20日
  • 创建了问题 3月20日

悬赏问题

  • ¥15 没输出运行不了什么问题
  • ¥20 输入import torch显示Intel MKL FATAL ERROR,系统驱动1%,: Cannot load mkl_intel_thread.dll.
  • ¥15 点云密度大则包围盒小
  • ¥15 nginx使用nfs进行服务器的数据共享
  • ¥15 C#i编程中so-ir-192编码的字符集转码UTF8问题
  • ¥15 51嵌入式入门按键小项目
  • ¥30 海外项目,如何降低Google Map接口费用?
  • ¥15 fluentmeshing
  • ¥15 手机/平板的浏览器里如何实现类似荧光笔的效果
  • ¥15 盘古气象大模型调用(python)
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部