`
zhengjie110120
  • 浏览: 2368 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

thrift 0.8 java客户端无法catch异常

 
阅读更多


问题描述:
    当方法返回值为thrift基本类型(i64,bool...)时,客户端无法捕捉异常。
    ps.当方法返回值为用户定义的类型时,不会出现该问题。
    注意 thrift 版本0.8
   
跟踪thrift代码发现,问题出现的原因:

step 1: 服务端,写数据

(基本类型) 不会先判断返回值是否为空,基本类型也无法判断是否为空
    oprot.writeStructBegin(STRUCT_DESC);
    oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
    oprot.writeI64(struct.success);
    oprot.writeFieldEnd();


(用户定义类型) 会先判断返回值是否为空
    if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (Province _iter3 : struct.success)
            {
              _iter3.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
    }


   
step 2: 客户端读数据

(基本类型)  服务端写数据时,一定会写入返回值的TField,所以读到的第一个TFIELD 一定会进入case0.  其中执行了  struct.setSuccessIsSet(true); 方法标示 返回值已写入
            switch (schemeField.id) {
                case 0: // SUCCESS
                    if (schemeField.type == TType.I64) {
                        struct.success = iprot.readI64();
                        struct.setSuccessIsSet(true);
                    }
                    else {
                        TProtocolUtil.skip(iprot, schemeField.type);
                    }
                    break;
                case 1: // USER_EXCEPTION
                    //................
                default:
                    TProtocolUtil.skip(iprot, schemeField.type);
                }


(用户定义类型) 服务端写数据时,经过判断未写入返回值TField,  因此直接进入case 1
        switch (schemeField.id) {
            case 0: // SUCCESS
              // ................
              break;
            case 1: // COMMON_EXCEPTION
             // .................
          }

         
step 3: 客户端处理返回结果 执行recv_****方法时


    if (result.isSetSuccess()) {
        return result.success;
    }
    if (result.commonException != null) {
       throw result.commonException;
    }

(基本类型)  由于基本类型在step2中执行了setSuccessIsSet(true);
            因此第一个if总是为真,在这步方法已经返回。
            不能够进入第二个if.捕捉异常
   
(用户定义类型) 用户类型。如果产生异常则跳过第一个if,能够在第二个if块中捕捉到异常




我想到的解决方法:
方法1.  更改step1
    oprot.writeStructBegin(STRUCT_DESC);
    oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
    oprot.writeI64(struct.success);
    oprot.writeFieldEnd();
    更改为
    oprot.writeStructBegin(STRUCT_DESC);
    if (this.isSetSuccess()) {
        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
        oprot.writeI64(struct.success);
        oprot.writeFieldEnd();
    }
   
方法2.     更改step3
    将recv_****方法中
    if (result.isSetSuccess()) {
        return result.success;
    }
    if (result.commonException != null) {
       throw result.commonException;
    }
   
    更改顺序变为
    if (result.commonException != null) {
       throw result.commonException;
    }
    if (result.isSetSuccess()) {
        return result.success;
    }
问题得到解决

但是由于  这样需要为每个生成的Iface修改代码,开发代价太大。所以想请教下大牛们是如何解决这个问题的。
   
   

分享到:
评论
1 楼 zhengjie110120 2012-05-16  
换成0.6.1 没有这个问题

相关推荐

    Thrift Java 服务器 客户端通信

    在Java环境中,Thrift提供了服务器和客户端的实现,使得Java应用能够方便地建立起高效的通信机制。下面我们将深入探讨Thrift在Java环境中的服务器和客户端通信过程。 首先,我们需要定义服务接口。这通常通过编写一...

    基于thrift开发的客户端和服务端

    通过Thrift,你可以用Java编写服务端,而用Python、C++或任何支持Thrift的其他语言编写客户端,实现无缝交互。Thrift还提供了许多优化功能,如多线程处理、异步调用和高级数据序列化选项,使得它成为构建分布式系统...

    Thrift下java服务器与客户端开发指南【精选文档】.doc

    Thrift下java服务器与客户端开发指南【精选文档】.doc

    Thrift RPC客户端的服务化框架代码

    生成代码后,Thrift会为每种目标语言(如Java、Python、C++等)创建相应的客户端和服务器端代码。客户端代码提供了调用远程服务的接口,服务器端代码则包含了处理这些调用的实际逻辑。例如,对于Java,客户端代码会...

    Thrift下java服务器与客户端开发指南[归纳].pdf

    4. 创建Java客户端 客户端代码同样基于Thrift生成的代码,创建一个`Client.java`文件,用于调用服务器上的服务: ```java import org.apache.thrift.TException; public class Client { public static void main...

    Thrift-java学习小结

    本文将基于Thrift的Java实现,总结学习过程中的一些关键知识点,旨在帮助理解Thrift的工作原理以及如何在Java环境中应用。 一、Thrift简介 Thrift是一种远程过程调用(RPC)框架,它通过定义一种中间描述文件(....

    Thrift下java服务器与客户端开发指南

    `--gen java` 参数告诉 Thrift 编译器我们需要生成 Java 代码,`namespace java Test` 定义了生成代码的 Java 包名。 ```thrift namespace java Test service Something { i32 ping() } ``` 执行 `thrift --gen ...

    Thrift下java服务器与客户端开发指南.pdf

    《Thrift下Java服务器与客户端开发指南》 Thrift 是一个高效的跨语言服务开发框架,由Facebook开源,主要用于构建可扩展且跨平台的服务。它通过定义一种中间表示(IDL,Interface Description Language)来描述数据...

    Thrift下java服务器与客户端开发指南文.pdf

    创建Java客户端相对简单,因为Thrift已经为我们生成了必要的客户端代码。主要步骤是建立一个连接到服务器的客户端实例,然后调用服务方法。 4. 编译及运行 4.1 使用Java编译器(javac)编译所有源文件,确保所有...

    thrift_java_demo和安装包

    客户端则使用Thrift生成的Java客户端类,连接服务端,进行通信。 - 这个测试项目可能是为了演示如何使用Thrift进行RPC(Remote Procedure Call)调用,包括服务的定义、服务端的实现、客户端的调用流程等。 - 项目...

    Thrift下java服务器与客户端开发指引.pdf

    4. **创建Java客户端** - **建立客户端连接**:客户端使用生成的`Something$Client`类来创建到服务器的连接。 - **调用服务**:通过客户端对象,我们可以调用`ping`方法,就像调用本地Java方法一样。 5. **编译及...

    thrift 的 java 和 python结合例子

    在这个"thrift的java和python结合例子"中,我们将探讨如何使用Thrift在Java和Python之间建立通信。 首先,Thrift通过定义接口描述文件(.thrift)来规范服务的接口。这个文件使用Thrift IDL(Interface Description...

    Thrift下java服务器与客户端开发指南实用.pdf

    4. **创建Java客户端** 客户端使用生成的`SomethingClient`类来连接服务器并调用服务: ```java public class Client { public static void main(String[] args) throws Exception { TTransport transport = ...

    GO语言通过Thrift服务器和客户端通信(经典)

    **GO语言通过Thrift服务器和客户端通信(经典)** 在软件开发中,跨语言通信是一个常见的需求,Thrift就是一种高效、轻量级的跨语言服务框架,它由Facebook开发并开源,支持多种编程语言,包括Go语言。本文将详细...

    Thrift下java服务器与客户端开发指南[借鉴].pdf

    创建Java客户端涉及创建一个连接到服务器的实例,并调用服务接口的方法。你可以创建一个`Client.java`文件,连接到服务器并调用`ping`方法。 4. 编译及运行 4.1 编译 使用Java编译器(`javac`)编译生成的和自定义...

    thrift java build jar

    本文将详细介绍如何使用 Thrift 在 Java 环境下构建 `.jar` 文件,以便在不同的 Java 应用中使用 Thrift 生成的服务。 1. **安装 Thrift** 首先,你需要在本地安装 Thrift 编译器。访问 Thrift 官方网站...

    Thrift下java服务器与客户端开发指南.doc

    Thrift下java服务器与客户端开发指南.doc

    Thrift java服务端、php客户端

    通过Thrift的编译器,这个IDL文件会被转换成Java代码,生成服务接口类(如`Calculator.java`)和服务处理类(如`CalculatorHandler.java`)。服务处理类实现了服务接口,具体执行业务逻辑。然后,开发者可以通过...

Global site tag (gtag.js) - Google Analytics