原包名是com.xxx,新包名是com.yyy 为了兼容,从老系统获取到字节流时,替换包名为com.yyy,得到新系统的bean。 序列化传递给老系统之前,先替换包名为com.xxx。
import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import java.io.*;
/** * <b>功能:</b>对象序列化工具类<br> */ public final class SerializeUtil { private SerializeUtil(){ }; /** * <b>功能描述:</b>对象序列化<br> * @param object 源数据对象 * @return */ public static byte[] serialize(Object object) { ObjectOutputStream oos = null; ByteArrayOutputStream baos = null;
String OLD_PACKAGE = "com.xxx"; String NEW_PACKAGE = "com.yyy"; try { // 序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(object); byte[] bytes = baos.toByteArray(); return changePathInSerializedData(bytes, NEW_PACKAGE, OLD_PACKAGE); } catch (Exception e) { throw new RuntimeException("aaaaa", e); } }
/** * <b>功能描述:</b>对象反序列化<br> * @param bytes 源数据对象 * @return */ public static Object unserialize(byte[] bytes) { ByteArrayInputStream bais = null; try { // 反序列化 bais = new ByteArrayInputStream(bytes); MyObjectInputStream ois = new MyObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { throw new RuntimeException("bbbb", e); } }
/** * 替换包名. * @param buffer 字节流 * @param fromPath 源包名 * @param toPath 目标包名 * @return 替换后的字节流 * @throws IOException */ public static byte[] changePathInSerializedData(byte[] buffer, String fromPath, String toPath) throws IOException { byte[] search = fromPath.getBytes("UTF-8"); byte[] replace = toPath.getBytes("UTF-8");
ByteArrayOutputStream f = new ByteArrayOutputStream();
for (int i = 0; i < buffer.length; i++) { // Search 2 bytes ahead to let us modify the 2 bytes length of the class // name (see Serialize format http://www.javaworld.com/community/node/2915 // ) boolean found = false; int searchMaxIndex = i + search.length + 2; if (searchMaxIndex <= buffer.length) { found = true; for (int j = i + 2; j < searchMaxIndex; j++) { if (search[j - i - 2] != buffer[j]) { found = false; break; } } } if (found) { int high = ((int) (buffer[i]) & 0xff); int low = ((int) (buffer[i + 1]) & 0xff); int classNameLength = (high << 8) + low; classNameLength += replace.length - search.length; // Write new length f.write((classNameLength >> 8) & 0xff); f.write((classNameLength) & 0xff); // Write replacement path f.write(replace); i = searchMaxIndex - 1; } else { f.write(buffer[i]); } }
f.flush(); f.close();
return f.toByteArray(); } }
/** * 替换包名. */ class MyObjectInputStream extends ObjectInputStream { private static Logger logger = LoggerFactory.getLogger(MyObjectInputStream.class); private static final String OLD_PACKAGE = "com.xxx"; private static final String NEW_PACKAGE = "com.yyy";
public MyObjectInputStream(InputStream arg0) throws IOException { super(arg0); }
@Override public Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { String name = desc.getName(); try { if (name.startsWith(OLD_PACKAGE)) { name = name.replace(OLD_PACKAGE, NEW_PACKAGE); return Class.forName(name); } } catch (ClassNotFoundException ex) { logger.warn(ex.getMessage()); }
return super.resolveClass(desc); } }
|