禁用Java序列化与IO流时,如何反序列化含可变长字符串的Flight类?
解决方案
因为禁止使用Java对象序列化工具和IO流类,我们可以通过自定义内存级的序列化/反序列化逻辑来处理source和destination这两个可变长度字符串,以下是几种实用方案:
方案一:基于长度前缀的字符串编码(最可靠)
这种方式通过先存储字符串的长度,再存储字符串内容,避免分隔符冲突问题,完全在内存中处理,不依赖任何IO流或序列化工具。
序列化逻辑(将字符串转成可解析的字节数组)
对于单个字符串:
- 把字符串转成UTF-8字节数组
- 将字节数组的长度(int类型,占4字节)转成字节序列
- 拼接长度字节和字符串字节,得到最终的序列化结果
反序列化逻辑(从字节数组还原字符串)
- 先读取前4字节,解析出字符串的字节长度
- 再读取对应长度的字节,转成UTF-8字符串
代码示例
在Flight类中添加自定义方法:
import java.nio.charset.StandardCharsets; public class Flight { // 原有字段、构造器、getters/setters不变... // 将source和destination序列化为字节数组(内存级操作) public byte[] serializeSourceDest() { byte[] sourceBytes = source.getBytes(StandardCharsets.UTF_8); byte[] destBytes = destination.getBytes(StandardCharsets.UTF_8); // 总长度:source长度(4字节) + source字节 + dest长度(4字节) + dest字节 byte[] result = new byte[4 + sourceBytes.length + 4 + destBytes.length]; // 写入source长度 System.arraycopy(intToBytes(sourceBytes.length), 0, result, 0, 4); // 写入source字节内容 System.arraycopy(sourceBytes, 0, result, 4, sourceBytes.length); int destStartIndex = 4 + sourceBytes.length; // 写入destination长度 System.arraycopy(intToBytes(destBytes.length), 0, result, destStartIndex, 4); // 写入destination字节内容 System.arraycopy(destBytes, 0, result, destStartIndex + 4, destBytes.length); return result; } // 从字节数组反序列化出source和destination public static String[] deserializeSourceDest(byte[] data) { // 解析source长度 int sourceLen = bytesToInt(data, 0); // 还原source字符串 String source = new String(data, 4, sourceLen, StandardCharsets.UTF_8); int destStartIndex = 4 + sourceLen; // 解析destination长度 int destLen = bytesToInt(data, destStartIndex); // 还原destination字符串 String destination = new String(data, destStartIndex + 4, destLen, StandardCharsets.UTF_8); return new String[]{source, destination}; } // 辅助方法:int转4字节数组 private static byte[] intToBytes(int value) { return new byte[]{ (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value }; } // 辅助方法:从字节数组指定位置解析int private static int bytesToInt(byte[] bytes, int offset) { return ((bytes[offset] & 0xFF) << 24) | ((bytes[offset+1] & 0xFF) << 16) | ((bytes[offset+2] & 0xFF) << 8) | (bytes[offset+3] & 0xFF); } }
方案二:基于特殊分隔符的字符串拼接(简单场景适用)
如果能确保source和destination中不会出现特定分隔符(比如###),可以直接用分隔符拼接字符串,反序列化时拆分即可:
序列化
public String serializeSourceDestStr() { return source + "###" + destination; }
反序列化
public static String[] deserializeSourceDestStr(String data) { // 限制拆分次数,避免destination中意外包含分隔符导致解析错误 return data.split("###", 2); }
注意:如果字符串可能包含分隔符,这种方法会出错,优先选择方案一。
方案三:内存级JSON解析(适合复杂场景)
如果项目允许引入轻量JSON库(比如Gson),可以直接将source和destination转成JSON字符串,反序列化时解析,全程在内存中操作,不涉及IO流或Java序列化工具:
代码示例(用Gson)
import com.google.gson.Gson; import com.google.gson.JsonObject; public class Flight { // 原有字段、构造器、getters/setters不变... public String serializeSourceDestJson() { JsonObject json = new JsonObject(); json.addProperty("source", source); json.addProperty("destination", destination); return new Gson().toJson(json); } public static String[] deserializeSourceDestJson(String jsonStr) { JsonObject json = new Gson().fromJson(jsonStr, JsonObject.class); return new String[]{ json.get("source").getAsString(), json.get("destination").getAsString() }; } }
内容的提问来源于stack exchange,提问作者tayron.vikranth
相关产品推荐
相关产品推荐

