我在项目中遇到一个问题:一个叫做WebSocketServer的类中注入一个RedisUtil工具类且WebSocketServer类有一个静态方法, 该类的静态方法调用该RedisUtil工具类的方法出现空指针,
WebSocketServer代码如下:
import cn.hutool.core.codec.Base64;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.okancha.constant.commonresultcode.CommonResultCode;
import com.okancha.utils.JWTUtil;
import com.okancha.utils.redis.RedisUtil;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ServerEndpoint("/websocket/{token}")
@Component
public class WebSocketServer {
@Autowired
private RedisUtil redisUtil;
private static RedisUtil RedisUtilStatic;
@PostConstruct
public void init() {
RedisUtilStatic = redisUtil;
}
static Log log = LogFactory.get(WebSocketServer.class);
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//接收userCode
private String userCode = null;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("token") String token) {
// 解密token
String userCode = JWTUtil.getAppUID(token);
if (StringUtils.isBlank(userCode)) {
log.error("用户token被串改过了");
return;
}
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在线数加1
log.info("有新窗口开始监听userCode: " + userCode + ",当前在线人数为" + getOnlineCount());
this.userCode = userCode;
try {
sendMessage("连接成功");
} catch (IOException e) {
log.error("websocket IO异常");
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
// 这里可以处理客户端的用户发送过来的信息message
log.info("收到来自客户端的用户userCode: " + userCode + "的信息: " + message);
for (WebSocketServer item : webSocketSet) {
item.sendInfo(userCode, item);
}
}
/**
* 群发自定义消息
*/
public static void sendInfo(String userCode, WebSocketServer item) {
try {
if (userCode.equals(item.userCode)) { // 如果是当前的用户的,那么就生成有效期只有一分钟的二维码
String timeStr = new Date().getTime() + StringUtils.EMPTY;
// 生成二维码
QrConfig config = new QrConfig(300, 300);
config.setMargin(2);
byte[] date = QrCodeUtil.generatePng(Base64.encode(timeStr), config);
// 把二维码变成base64
String encode = Base64.encode(date);
// 发送数据
item.sendMessage(encode);
// 保存在redis中,有效期是一分钟
RedisUtilStatic.setEx(CommonResultCode.BOOK_BAR_TEMPORARY_QRCODE + userCode, timeStr, 1, TimeUnit.MINUTES);
log.info("推送消息到userCode: " + item.userCode + ",推送内容:" + encode);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 实现服务器主动推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
上面的代码可以看到静态方法sendInfo调用RedisUtil工具类的方法, 刚开始的时候出现了redisUtil是null的情况,后来只需要这样配置就对了,代码如下:
@Autowired
private RedisUtil redisUtil;
private static RedisUtil RedisUtilStatic;
@PostConstruct
public void init() {
RedisUtilStatic = redisUtil;
}
配置完以后就不会出现空指针啦
如果你想看到我的RedisUtil工具类是怎么写的,详情看:
https://blog.csdn.net/qq_26106607/article/details/102307615