-
Notifications
You must be signed in to change notification settings - Fork 224
migrate hsf 2 springcloud serialization
HSF和Dubbo的早期版本采用 hessian2 进行编码。 hessian2 是一种跨语言的二进制编码协议, HSF和Dubbo基于这个协议进行了自定义, 开发了 hessian-lite 实现。 hessian-lite 的实现不是跨语言的, 能够支持非常复杂 JAVA 场景的序列化,包括泛型、抽象类等。
将HSF和Dubbo的RPC修改为Spring Cloud(参考方案), 会存在很多序列化问题。下面列举一些常见场景及其解决方案。 这些问题,很多都和业务代码的特殊用法有关,在Spring Cloud场景下,需要有不同的写法。
为了描述方便,下面用hessian和jackson分别代表两种框架的序列化方式。
Map<String, Object> model = new HashMap<>();
model.put("key1", (byte)1);
model.put("key2", 1);
Map类型在hessian和jackson都能序列化。hessian反序列化能够得到value的原始类型,但是jackson则不一定。 比如上面的代码, hessian能够得到key1为byte, key2为integer,但是jackson得到的都是integer。
class Base {}
class Child extends Base {}
public Base echo(Base b) { if (b instanceof Child) {} }
jackson在反序列化以后,只能得到基类信息,子类信息和类型都丢失了。 如果需要得到子类信息,需要在基类和子类增加相应的标签:
@JsonTypeInfo(use = Id.CLASS, defaultImpl = Base.class)
class Base {}
@JsonTypeInfo(use = Id.CLASS, defaultImpl = Child.class)
class Child extends Base {}
class Generic<T> {T data}
泛型序列化, jackson不会包含data的类型信息。这个问题和基类序列化问题类似。 如果基类增加了@JsonTypeInfo, 泛型的属性也需要增加这个信息,否则会导致反序列化失败。
class Generic<T> {
@JsonTypeInfo(use = Id.CLASS
T data;
}
如果存在微服务A、B、C, A是jackson应用,B、C是hessian应用, A调用B、B调用C, 有些业务需要在A定制ObjectMapper,将日期序列化为类似yyyy-MM-dd的格式。 将B、C都改造为jackson应用后,在会导致B调用C的时候,B序列化日期类型为yyyy-MM-dd的格式, C无法反序列化。 这种情况,建议统一日期的格式为ISO标准格式,前后台都遵循这个标准解析。
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss Z", timezone="America/New_York")
Date time
Spring Cloud Huawei 1.7.1-2020.0.x 版本提供了兼容性方案,可以采用hessian2编码。 例子如下:
@PostMapping(path = "base", consumes = "x-application/hessian2",
produces = "x-application/hessian2")
Base base(@RequestBody Base b);
-
使用Spring Cloud Huawei功能
-
使用服务治理
-
生态集成
-
迁移改造问题
-
配置参考
-
优秀实践
-
常见问题