首頁>技術>

由於thrift的型別沒有類似java的Object型別,當我們想用thrift來定義一個具體型別不確定的物件時候,會有不知如何定義的困擾。

方法一:使用聯合(union)

union的特點是結構中的每個field之間的關係是互斥的,即只能有一個field被使用被賦值。所以可以根據我們未知型別物件的類型範圍定義一個union

union JavaObjectArg {  1: i32 int_arg;  2: i64 long_arg;  3: string string_arg;  4: bool bool_arg;  5: binary binary_arg;  6: double double_arg;}struct OneResp {	1: list<JavaObjectArg> myList,}

union的使用方式

可以透過生成的JavaObjectArg.java中的standardSchemeReadValue方法獲取,對應的型別

protected Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TField field) throws org.apache.thrift.TException

或者,透過對應型別的get方法獲得結果。例如獲取*int*型別的結果

public int getInt_arg() {	if (getSetField() == _Fields.INT_ARG) {		return (Integer)getFieldValue();	} else {		throw new RuntimeException("Cannot get field 'int_arg' because union is currently set to " + getFieldDesc(getSetField()).name);	}}

方法二:使用特殊型別(binary)

binary:是未編碼的位元組序列

類似,當我們想定義一個List<Object>時

struct TwoResp {	1: list<binary> myList,}

生成後,會變成ByteBuffer型別,根據需要的型別對應進行轉換即可。

public List<ByteBuffer> myList;

終極方法:序列化

終極方案當然還是先把包含Object型別的物件或者集合,先序列化成一個jsonString。此時,在thrift中定義成string即可。使用時,由呼叫端將這個string物件根據約定的物件反序列化後即可獲得需要的型別。

以下面的介面為例,透過Jackson序列化。

service ITMuouThriftService {	string testScene(string param);}

服務端序列化:

Map<String, Object> decisionMap = Maps.newHashMapWithExpectedSize(1);	decisionMap.put("res": 1);return new ObjectMapper().writeValueAsString(decisionMap)

呼叫端反序列化:

TypeReference<Map<String, Object>> MAP_TYPE_REF = new TypeReference<Map<String, Object>>() { };String res = muouThriftService.testScene("test");Map<String, Object> resultMap = new ObjectMapper().readValue(res, MAP_TYPE_REF);

10
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • eBPF 入門之程式設計