- Hessian依存関係の設定
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
- シリアライズとデシリアライズの実装
public static byte[] convertToBinary(Object data) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
Hessian2Output serializer = new Hessian2Output(byteStream);
try {
serializer.writeObject(data);
serializer.flush();
return byteStream.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Serialization failed", e);
}
}
public static Object convertFromBinary(byte[] binaryData) {
ByteArrayInputStream stream = new ByteArrayInputStream(binaryData);
Hessian2Input deserializer = new Hessian2Input(stream);
try {
return deserializer.readObject();
} catch (Exception e) {
throw new RuntimeException("Deserialization failed", e);
}
}
Hessianのシリアライズ処理はHessian2Outputクラス、デシリアライズはHessian2Inputクラスを用いて実現されます。基本的なフローはバイナリストリームの準備→シリアライザによるデータ変換→ストリームのフラッシュという流れです。
- シリアライズの内部処理
3.1 シリアライザの初期化
Hessian2Outputの内部では、8KBのバッファを用意し、シリアライズ処理を効率化しています。初期化時にすべての参照情報をリセットし、ストリームを設定します。
3.2 オブジェクトシリアライズの処理
シリアライズ処理では、オブジェクトの型に基づき適切なシリアライザを選択します。基本データ型の処理は以下のようになります:
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
if (obj == null) {
out.writeNull();
return;
}
Serializer serializer = getSerializerFactory().getSerializer(obj.getClass());
serializer.writeObject(obj, out);
}
基本型のシリアライザでは、文字列や数値などのタイプに応じて異なる処理を実行します。例えば文字列のシリアライズでは、以下の手順で処理されます:
public void writeString(String value) throws IOException {
if (value == null) {
writeNull();
return;
}
int length = value.length();
if (length <= MAX_DIRECT_STRING) {
writeDirectString(value, length);
} else {
writeChunkedString(value, length);
}
}
3.3 カスタムオブジェクトのシリアライズ
カスタムクラスのシリアライズでは、クラス定義の記録とインスタンスデータの書き込みが行われます:
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
if (out.addReference(obj)) return;
Class<?> clazz = obj.getClass();
int refId = out.startObject(clazz.getName());
if (refId >= 0) {
writeInstance(obj, out);
} else {
writeClassDefinition(out, clazz);
writeInstance(obj, out);
}
}
- デシリアライズの内部処理
デシリアライズは、入力ストリームから各データのタイプを判別し、適切な処理を実行します:
public Object readObject() throws IOException {
int typeTag = readByte();
switch (typeTag) {
case 'S': return readString();
case 'I': return readInt();
case 'O': return readObjectInstance();
case 'N': return null;
default: throw new IOException("Unknown type: " + (char)typeTag);
}
}
オブジェクトの復元では、クラス定義を読み込み、その後インスタンスを構築します:
private Object readObjectInstance() throws IOException {
String className = readString();
ObjectDefinition def = readObjectDefinition(className);
Object instance = createInstance(def);
readFieldValues(instance, def);
return instance;
}
カスタムオブジェクトの復元では、クラス定義に基づいて各フィールドを順次復元し、最終的に完全なオブジェクトを構築します。