多语言序列化
跨语言对象图序列化
序列化内置类型
Apache Fory™ 可以自动序列化编程语言的常见数据类型:primitive numeric types, string, binary, array, list, map 等。
Java
import org.apache.fory.*;
import org.apache.fory.config.*;
import java.util.*;
public class Example1 {
public static void main(String[] args) {
Fory fory = Fory.builder().withLanguage(Language.XLANG).build();
List<Object> list = ofArrayList(true, false, "str", -1.1, 1, new int[100], new double[20]);
byte[] bytes = fory.serialize(list);
// bytes can be data serialized by other languages.
fory.deserialize(bytes);
Map<Object, Object> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", list);
map.put("k3", -1);
bytes = fory.serialize(map);
// bytes can be data serialized by other languages.
fory.deserialize(bytes);
}
}
Python
import pyfory
import numpy as np
fory = pyfory.Fory()
object_list = [True, False, "str", -1.1, 1,
np.full(100, 0, dtype=np.int32), np.full(20, 0.0, dtype=np.double)]
data = fory.serialize(object_list)
# bytes can be data serialized by other languages.
new_list = fory.deserialize(data)
object_map = {"k1": "v1", "k2": object_list, "k3": -1}
data = fory.serialize(object_map)
# bytes can be data serialized by other languages.
new_map = fory.deserialize(data)
print(new_map)
Golang
package main
import forygo "github.com/apache/fory/fory/go/fory"
import "fmt"
func main() {
list := []interface{}{true, false, "str", -1.1, 1, make([]int32, 10), make([]float64, 20)}
fory := forygo.NewFory()
bytes, err := fory.Marshal(list)
if err != nil {
panic(err)
}
var newValue interface{}
// bytes can be data serialized by other languages.
if err := fory.Unmarshal(bytes, &newValue); err != nil {
panic(err)
}
fmt.Println(newValue)
dict := map[string]interface{}{
"k1": "v1",
"k2": list,
"k3": -1,
}
bytes, err = fory.Marshal(dict)
if err != nil {
panic(err)
}
// bytes can be data serialized by other languages.
if err := fory.Unmarshal(bytes, &newValue); err != nil {
panic(err)
}
fmt.Println(newValue)
}
JavaScript
import Fory from "@apache-fory/fory";
/**
* @apache-fory/hps use v8's fast-calls-api that can be called directly by jit, ensure that the version of Node is 20 or above.
* Experimental feature, installation success cannot be guaranteed at this moment
* If you are unable to install the module, replace it with `const hps = null;`
**/
import hps from "@apache-fory/hps";
const fory = new Fory({ hps });
const input = fory.serialize("hello fory");
const result = fory.deserialize(input);
console.log(result);
Rust
use chrono::{NaiveDate, NaiveDateTime};
use fory::{from_buffer, to_buffer, Fory};
use std::collections::HashMap;
fn run() {
let bin: Vec<u8> = to_buffer(&"hello".to_string());
let obj: String = from_buffer(&bin).expect("should success");
assert_eq!("hello".to_string(), obj);
}
序列化自定义类型
序列化用户定义的类型需要使用注册 API 注册自定义类型,以便在不同语言中建立类型之间的映射关系。
Java
import org.apache.fory.*;
import org.apache.fory.config.*;
import java.util.*;
public class Example2 {
public static class SomeClass1 {
Object f1;
Map<Byte, Integer> f2;
}
public static class SomeClass2 {
Object f1;
String f2;
List<Object> f3;
Map<Byte, Integer> f4;
Byte f5;
Short f6;
Integer f7;
Long f8;
Float f9;
Double f10;
short[] f11;
List<Short> f12;
}
public static Object createObject() {
SomeClass1 obj1 = new SomeClass1();
obj1.f1 = true;
obj1.f2 = ofHashMap((byte) -1, 2);
SomeClass2 obj = new SomeClass2();
obj.f1 = obj1;
obj.f2 = "abc";
obj.f3 = ofArrayList("abc", "abc");
obj.f4 = ofHashMap((byte) 1, 2);
obj.f5 = Byte.MAX_VALUE;
obj.f6 = Short.MAX_VALUE;
obj.f7 = Integer.MAX_VALUE;
obj.f8 = Long.MAX_VALUE;
obj.f9 = 1.0f / 2;
obj.f10 = 1 / 3.0;
obj.f11 = new short[]{(short) 1, (short) 2};
obj.f12 = ofArrayList((short) -1, (short) 4);
return obj;
}
// mvn exec:java -Dexec.mainClass="org.apache.fory.examples.Example2"
public static void main(String[] args) {
Fory fory = Fory.builder().withLanguage(Language.XLANG).build();
fory.register(SomeClass1.class, "example.SomeClass1");
fory.register(SomeClass2.class, "example.SomeClass2");
byte[] bytes = fory.serialize(createObject());
// bytes can be data serialized by other languages.
System.out.println(fory.deserialize(bytes));
}
}
Python
from dataclasses import dataclass
from typing import List, Dict, Any
import pyfory, array
@dataclass
class SomeClass1:
f1: Any
f2: Dict[pyfory.Int8Type, pyfory.Int32Type]
@dataclass
class SomeClass2:
f1: Any = None
f2: str = None
f3: List[str] = None
f4: Dict[pyfory.Int8Type, pyfory.Int32Type] = None
f5: pyfory.Int8Type = None
f6: pyfory.Int16Type = None
f7: pyfory.Int32Type = None
# int type will be taken as `pyfory.Int64Type`.
# use `pyfory.Int32Type` for type hint if peer
# are more narrow type.
f8: int = None
f9: pyfory.Float32Type = None
# float type will be taken as `pyfory.Float64Type`
f10: float = None
f11: pyfory.Int16ArrayType = None
f12: List[pyfory.Int16Type] = None
if __name__ == "__main__":
f = pyfory.Fory()
f.register_class(SomeClass1, type_tag="example.SomeClass1")
f.register_class(SomeClass2, type_tag="example.SomeClass2")
obj1 = SomeClass1(f1=True, f2={-1: 2})
obj = SomeClass2(
f1=obj1,
f2="abc",
f3=["abc", "abc"],
f4={1: 2},
f5=2 ** 7 - 1,
f6=2 ** 15 - 1,
f7=2 ** 31 - 1,
f8=2 ** 63 - 1,
f9=1.0 / 2,
f10=1 / 3.0,
f11=array.array("h", [1, 2]),
f12=[-1, 4],
)
data = f.serialize(obj)
# bytes can be data serialized by other languages.
print(f.deserialize(data))