0

我有一个protocol buffer文件:

syntax = "proto3";
package v1api;
option java_multiple_files = true;
option java_package = "myApp.v1";
option java_outer_classname = "V1";

service API {
    rpc Login(LoginRequest) returns (LoginResponse)
}

message LoginRequest {
    int pin = 1
}

message LoginResponse {
    string token = 1
}

我的服务器是用 Go(一种可以返回多个值的语言)编写的,我的客户端是一个 Android 应用程序。

当我使用这个 protoBuf 为服务器生成 Go 代码时,它类似于:

...
func (c *aPIClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) {
    out := new(LoginResponse)
    err := grpc.Invoke(ctx, "/v1api.API/Login", in, out, c.cc, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
...

请注意,有两个返回值,(*LoginResponse, error)

现在,当我使用这个 protoBuf 为我的 Android 端生成 Java 代码时,我得到如下信息:

public myApp.v1.LoginResponse login(myApp.v1.LoginRequest request) {
    return blockingUnaryCall(getChannel(), METHOD_LOGIN, getCallOptions(), request);
}

请注意,这里只有一个像 Java 允许的返回值,myApp.v1.LoginResponse.

我的问题是,如果服务器返回错误(例如:)return nil, err,我将如何在我的 Android 端获得第二个返回值。

4

2 回答 2

2

在 Go 中,您的Login方法返回的错误将被转换为有线格式状态code并由messagegRPC 使用。在您的情况下,如果您返回 status.Status,代码和消息将被发送并在 Java 端显示为StatusRuntimeException。如果您返回非Status错误,gRPC 会将其转换为UNKNOWN代码,但会保留消息。

这就是 Go 有两个返回值,而 Java 只有一个的原因。Java 可以通过在其位置抛出异常来“返回”辅助值。

于 2017-05-22T19:57:37.777 回答
0

由于 Java 不支持多个返回值,所以在将 protoBuf 生成到 java 代码中时,通过抛出异常来传达错误。try-catch在一个块中进行 gRPC 调用并捕获StatusRuntimeException调用可能抛出的任何内容。

于 2017-05-22T12:37:50.170 回答