如何判断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
相关产品推荐
相关产品推荐

