【报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 服务器

###解决了,我之前不知道为什么 @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);
    }
}

完美解决