thrift/swift:ThriftMethodProcessor代码分析

来源:互联网 发布:中子星 知乎 编辑:程序博客网 时间:2024/06/14 08:25

thrift是一种跨语言的RPC框架,为了保证在各种语言下都能正确表述,IDL语言在设计的时候就只能选取各种语言的共性。
比如对于null,虽然在java中定义一个字段为Integer类型,那么这个字段就可以为null,但thrift不允许primitive类型的数据字段为null,因为在c/c++的struct的字段中没有null的概念。做为方法的参数传递,primitive类型也是同样的道理。
所以thrift client 发送调用服务方法时,如果方法的参数类型为Integer,你即使将该参数设置为null,服务端收到的值也不是null,而是0.

经过反复跟踪我总算找到将null参数转为0的位置,就在服务端com.facebook.swift.service.ThriftMethodProcessor的私有方法readArguments中,下面是readArguments的代码,注意代码中作者添加的中文注释

private Object[] readArguments(TProtocol in)            throws Exception    {        try {            int numArgs = method.getParameterTypes().length;            // 初始化参数数组,初始值都为null            Object[] args = new Object[numArgs];            TProtocolReader reader = new TProtocolReader(in);            // 先从收到的数据库根据fieldId 将不为null的服务方法参数解析出来,            // 为null的参数不在收到的数据中出现            // 所以这个循环结束时,不为null的参数已经被正确解析并保存到args的对应位置了            // client填null(原本就是null)的参数对应的位置就是null,            reader.readStructBegin();            while (reader.nextField()) {                short fieldId = reader.getFieldId();                ThriftCodec<?> codec = parameterCodecs.get(fieldId);                if (codec == null) {                    // unknown field                    reader.skipFieldData();                }                else {                    // 将参数调用对应用的解码器ThriftCodec解析成正确的数据类型,                    // 存入arg数组对应的位置                    args[thriftParameterIdToJavaArgumentListPositionMap.get(fieldId)] = reader.readField(codec);                }            }            reader.readStructEnd();            // 在下面这个循环中,对args数组中为null的参数进行检查,            // 如果是primitive类型则调用 Defaults.defaultValue方法返回缺省值            // 比如对于Integer类型缺省值就是0            // 如果删除掉这一整段循环代码,service端收到的Integer参数就可以是null            int argumentPosition = 0;            for (ThriftFieldMetadata argument : parameters) {                if (args[argumentPosition] == null) {                    Type argumentType = argument.getThriftType().getJavaType();                    if (argumentType instanceof Class) {                        Class<?> argumentClass = (Class<?>) argumentType;                        argumentClass = Primitives.unwrap(argumentClass);                        args[argumentPosition] = Defaults.defaultValue(argumentClass);                    }                }                argumentPosition++;            }            return args;        }        catch (TProtocolException e) {            // TProtocolException is the only recoverable exception            // Other exceptions may have left the input stream in corrupted state so we must            // tear down the socket.            throw new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage());        }    }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 5个月宝宝腿短怎么办 5个月宝宝太瘦怎么办 宝宝喝了浓奶粉怎么办 一岁把尿不尿怎么办 五个月的宝宝大便干燥怎么办 婴儿便秘怎么办什么方法最有效 8个月小孩便秘怎么办 1个月新生儿便秘怎么办 新生儿头竖立0分怎么办 20天的宝宝便秘怎么办 出生23天的宝宝便秘怎么办 喝奶粉的宝宝便秘怎么办 抱孩子抱的驼背怎么办 4岁宝宝不拉屎怎么办 小朋友大便拉不出来怎么办 儿童便秘拉不出来怎么办 没感冒喉咙有痰怎么办 宝宝喂不进去药怎么办 新生儿只放屁不拉大便怎么办 新生儿腹胀不拉大便怎么办 8月宝宝咳嗽有痰怎么办 2个月婴儿惊吓怎么办 吃了米粉不拉屎怎么办 奇异果奶昔苦了怎么办 8个月宝宝偏瘦怎么办 一岁宝宝螺旋腿怎么办 七个月宝宝晚上咳嗽厉害怎么办 孕7个月感冒咳嗽怎么办 4个月婴儿肺炎怎么办 宝宝吃胡萝卜泥拉肚子怎么办 宝宝吃土豆泥不消化怎么办 五个月宝宝奶睡怎么办 橘子和牛奶一起吃了怎么办 半岁宝宝不喝水怎么办 一岁宝宝总是便秘怎么办 1岁的宝宝不喝水怎么办 两月宝宝不喝水怎么办 破壁机打出的果汁很浓稠怎么办 榨的果汁不甜怎么办 11个月宝宝吃盐怎么办 1岁半宝宝长牙慢怎么办