thrift如何定义Java中的Object类型
由于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时
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);
git地址: