有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是否可以检查proto文件中的枚举值?

我想验证生成的Java代码中的枚举值。我有以下原始文件:

syntax = "proto3";

import "google/protobuf/empty.proto";

option java_multiple_files = true;
option java_package = "com.package";

package helloworld;

service SomeService {
    rpc DoAction (Request) returns (google.protobuf.Empty) { }
}

enum Currency {
    EUR = 0;
    GBP = 1;
    USD = 2;
}

message Request {
    string id = 1;
    Currency currency = 2;
}

我想在由protobuf生成的代码中对货币枚举进行一些验证,如果值不适用于提供的枚举,则删除错误消息(例如:invalid currency)。可能吗


共 (1) 个答案

  1. # 1 楼答案

    您可以验证它,但也应该注意Protobuf枚举的细微差别

    1. 始终为每个枚举包含一个UNKNOWN = 0;枚举值。当Protobuf不知道枚举值对应什么时,它会将其设置为默认值。这可以让你检测到一个带有新代码的新客户端何时使用了一个服务器无法理解的值。另外,如果字段未设置,它自然等于UNKNOWN,让我们检查一下字段是否不存在。(如果确实希望允许不存在的枚举,请将它们包装在message{}中)

    2. 在服务器应用程序处理程序中,您应该检查客户机提供了哪一个受支持的值。如果不是其中之一,您应该使用INVALID_ARGUMENT状态代码使RPC失败:

        out: {
          switch (req.getCurrency()) {
            case EUR: 
            case GBP:
            case USD: break out;
            case UNKNOWN:
              responseObserver.onError(
                  Status.INVALID_ARGUMENT
                      .withDescription("bad currency " + req.getCurrency())
                      .asRuntimeException());
              return;
          }
          throw new AssertionError("missed case!");
        }
        // keep handling the request
    

    此代码检查代码是否是受支持的代码之一。如果出现不受支持的代码,它将由UNKNOWN案例处理,并提前返回错误。如果修改proto并添加了更多案例,静态分析将捕获丢失的案例(或抛出断言错误)。请注意,如果客户端更新其proto,则不会发生这种情况。避免使用default案例,因为在修改proto时很容易忽略它。或者,您可以将所有受支持的案例放在地图中,并检查它是否存在