You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断InputStream空/Null字符串?服务端ObjectInputStream空值检测问题

问题2:处理ObjectInputStream读取null List的异常问题

从你给的客户端代码来看,首先就有个明显的坑:当str是null时,调用str.getBytes()会直接抛出NullPointerException,根本到不了发送数据的步骤!所以先得把客户端的null处理做好,再来看服务端的检测问题。

先理清核心逻辑:

ObjectOutputStream是支持写入null对象的——调用oos.writeObject(null)完全合法,服务端用ois.readObject()会直接返回null,不会抛出异常。你遇到的问题大概率是客户端的发送流程有问题,或者混淆了“发送null字符串”和“发送null List”的场景。

分场景给出解决方案:

场景1:你实际要发送的是null字符串(而非List)

客户端需要先处理null的情况,避免空指针:

String str = null;
byte[] input;
if (str == null) {
    // 约定用空字节数组表示null,或者自定义一个特殊标记(比如长度为1的字节,值为0)
    input = new byte[0];
} else {
    // 一定要指定字符集,避免不同环境下编码不一致
    input = str.getBytes(StandardCharsets.UTF_8);
}

// AES加密步骤
cipherAES.init(Cipher.ENCRYPT_MODE, encryptionKey, iv);
byte[] encryptedData = cipherAES.doFinal(input);

// 发送时先写数据长度,解决粘包问题
outputStream.writeInt(encryptedData.length);
outputStream.write(encryptedData);
outputStream.flush();

服务端对应处理:

// 先读数据长度
int dataLength = inputStream.readInt();
byte[] encryptedData = new byte[dataLength];
inputStream.readFully(encryptedData);

// 解密
cipherAES.init(Cipher.DECRYPT_MODE, encryptionKey, iv);
byte[] decryptedData = cipherAES.doFinal(encryptedData);

// 判断是否为null/空内容
if (decryptedData.length == 0) {
    System.out.println("收到null或空字符串");
} else {
    String receivedStr = new String(decryptedData, StandardCharsets.UTF_8);
    // 处理正常字符串
}

场景2:你确实要发送null的List对象

客户端要先序列化null List,再加密发送:

List<?> targetList = null;
// 把对象序列化成字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
    oos.writeObject(targetList); // 写入null完全合法
}
byte[] serializedData = baos.toByteArray();

// AES加密
cipherAES.init(Cipher.ENCRYPT_MODE, encryptionKey, iv);
byte[] encryptedData = cipherAES.doFinal(serializedData);

// 发送长度+加密数据
outputStream.writeInt(encryptedData.length);
outputStream.write(encryptedData);
outputStream.flush();

服务端反序列化处理:

int dataLength = inputStream.readInt();
byte[] encryptedData = new byte[dataLength];
inputStream.readFully(encryptedData);

// 解密
cipherAES.init(Cipher.DECRYPT_MODE, encryptionKey, iv);
byte[] decryptedData = cipherAES.doFinal(encryptedData);

// 反序列化对象
try (ByteArrayInputStream bais = new ByteArrayInputStream(decryptedData);
     ObjectInputStream ois = new ObjectInputStream(bais)) {
    List<?> receivedList = (List<?>) ois.readObject();
    if (receivedList == null) {
        System.out.println("收到null的List");
    } else {
        // 处理正常List
    }
}

为什么你的原方法无效?

  • ois.available():这个方法只能告诉你当前有多少字节可以无阻塞读取,完全不能用来判断对象是否为null,甚至不能判断是否有完整的对象可以读取。
  • ois.readObject() != null:如果客户端正确发送了null对象,这个判断是有效的,但你的客户端代码在发送前就抛出了NPE,根本没把数据发出去,所以服务端要么读不到数据,要么读到的是损坏的加密数据,自然会抛出异常。

内容的提问来源于stack exchange,提问作者cd4user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:23:04