thrift/swift:服务端数据类型和client端数据类型之间的直接转换
需求描述我们知道, 解决方案首先需要找到 /** 从一个数据对象Object,读取ThriftFieldMetadata指定的字段的值 */
com.facebook.swift.codec.internal.reflection.AbstractReflectionThriftCodec#getFieldValue(Object instance,ThriftFieldMetadata field)
/** 根据Map中字段值构造一个数据对象 */
com.facebook.swift.codec.internal.reflection.ReflectionThriftStructCodec#constructStruct(Map<Short,Object> data)
/** 从数据流protocol读取字段值转成数据对象 T */
T com.facebook.swift.codec.internal.reflection.ReflectionThriftStructCodec.read(TProtocol protocol)
/** 将数据对象instance写入数据流protocol */
void com.facebook.swift.codec.internal.reflection.ReflectionThriftStructCodec.write(T instance,TProtocol protocol)
通过这几个方法看懂了swift的数据对象转换机制,就可以参照这个机制实现服务端数据类型和client数据类型的直接转换。 /** 构造{@code metadata}指定类型的实例并填充字段 */
public static <T>T constructStruct(Map<Short,Object> data,ThriftStructMetadata metadata) throws Exception;
/** 填充{@code instance}实例的字段 */
public static <T>T fillStructField(Map<Short,ThriftStructMetadata metadata,T instance)
throws Exception
/** 获取{@code field}指定的字段值 */
public static Object getFieldValue(Object instance,ThriftFieldMetadata field) throws Exception ;
/** 根据{@code metadata}类型数据获取{@code instance}实例所有的字段值 */
public static Map<Short,Object> getFiledValues(Object instance,ThriftStructMetadata metadata);
应用示例以下是调用上面的方法实现的转换器 import static com.google.common.base.Preconditions.*;
import java.util.Map;
import com.facebook.swift.codec.metadata.ThriftStructMetadata;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import static net.gdface.thrift.ThriftUtils.*;
/** * 有{@link com.facebook.swift.codec.ThriftStruct}注释的类型之间的转换 * @author guyadong * * @param <L> 源数据类型,client或服务端java bean数据类型 * @param <R> 目标数据类型,L对应的服务或client端java bean数据类型 */
public class ThriftStructTransformer<L,R> implements Function<L,R>{
/** 源数据类型的thrift数据结构描述对象 */
private final ThriftStructMetadata leftMetadata;
/** 目标数据类型的thrift数据结构描述对象 */
private final ThriftStructMetadata rightMetadata;
/** 构造方法 */
public ThriftStructTransformer(Class<L> left,Class<R> right) {
// 根据数据类型生成thrift数据结构描述对象
this.leftMetadata= CATALOG.getThriftStructMetadata(checkNotNull(left,"left is null"));
this.rightMetadata= CATALOG.getThriftStructMetadata(checkNotNull(right,"right is null"));
}
/** 源类型到目标数据类型转换实现 */
@Override
public R apply(L input) {
if(null == input){
return null;
}
try {
// 读取所有字段值
Map<Short,Object> data = getFiledValues(input,leftMetadata);
// 根据字段值构造目标数据对象
return constructStruct(data,rightMetadata);
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder()
.append("ThriftStructTransformer [leftClass=")
.append(leftMetadata.getStructType())
.append(",rightClass=")
.append(rightMetadata.getStructType())
.append("]");
return builder.toString();
}
}
完整代码参见: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |