首页 文章

列表的节流(de)序列化

提问于
浏览
1

在Thrift中,在对服务的方法调用的上下文中,列表可以直接用作参数或返回类型 . 如果你需要显式的对象(反)序列化,是否有一种方便的方法(在Java中)使用Thrift(de)序列化List <TBase>而不必将它作为一个单独的结构包装在thrift IDL中?

更具体地说,假设我已经在节俭中定义了

struct A {
    1: required long x;
    2: required long y;
}

我可以通过定义(de)序列化这些列表

struct ListOfA {
    1: required list<A> theList;
}

然后

ListOfA myList = ...
TSerializer serializer = new TSerializer();
byte[] mySerializedList = serializer.serialize(myList);

我的问题是,是否可以避免仅包含列表的额外结构的这种(略微不优雅的)定义 .

以下不起作用,因为TSerializer.serialize需要TBase

List<A> myList = ...   // List<A> instead of ListOfA
TSerializer serializer = new TSerializer();
byte[] mySerializedList = serializer.serialize(myList); //does not compile

在IDL中使用typedef已经有所帮助,但它们似乎没有被翻译成Java类

typedef list<A> ListOfA

=> ListOfA未在生成的Java代码中定义 .

1 回答

  • 1

    我的问题是,是否可以避免仅包含列表的额外结构的这种(略微不优雅的)定义

    我建议相反:做一个使用包装结构的“低效”步骤 .

    Thrift允许任意数量的输入参数 . 但是,可以有 only one return value . 没有 varout 参数或多个返回值之类的东西,因此您实际上限制为最多一个返回值以返回您需要返回的任何数据 .

    发挥作用的第二个方面是 soft-versioning . Thrift允许稍后增强接口和数据结构,而不会破坏旧服务或客户端 . 如果你决定这样做

    struct Bar { /*some data*/ }
    
    service Foo {
        list<Bar> GiveMeTheData()
    }
    

    你基本上把自己从这个机制中切除了 . 因为返回的 list<Bar> 无法使用新的其他成员进行扩展 . 在这种情况下,您将不得不添加另一个电话 .

    相比之下,通过使用包装 struct ,可以轻松扩展返回数据,并且支付的价格不是那么高:

    struct Bar { /*some data*/ }
    
    struct FooResult { 
      1: list<Bar>   list
      // new members here
    }
    
    service Foo {
        FooResult GiveMeTheData()
    }
    

    此外,后者还允许返回NULL列表,这对于第一个布局是不可能的 .

相关问题