proto3.任何人都无法掩盖JSON

发布于 2025-02-07 01:37:16 字数 2585 浏览 2 评论 0原文

发送

我的proto

service GraphService {
  rpc insertGraphData (InsertRequest) returns (google.protobuf.StringValue) {}
}

message InsertRequest {
  string tagName = 1;
  map<string, google.protobuf.Any> tagProperties = 2;
}

当我使用proto3将像以下我的客户端请求实体

InsertRequest.newBuilder()
                .setTagName("facebook")
                .putTagProperties("userName", Any.newBuilder().setValue(ByteString.copyFrom("zzz", StandardCharsets.UTF_8)).build())
                .build()

时,我的graphRpcService这样的praghrpcservice

@GrpcService
@Slf4j
@RequiredArgsConstructor
public class GraphRpcService extends GraphServiceGrpc.GraphServiceImplBase {

    @Override
    public void insertGraphData(InsertRequest request, StreamObserver<StringValue> responseObserver) {
        StreamObserverDelegate.build(responseObserver).execute(()->{
       InsertRequest insertRequest = toJava(request, A.class);
//...
            return null;
        });
    }

    public static <T> T toJava(Message sourceMessage, Class<T> clazz) {
        if (sourceMessage != null) {
            try {
                return JSON.parseObject(JsonFormat.printer().includingDefaultValueFields().print(sourceMessage), clazz);
            } catch (InvalidProtocolBufferException e) {
                logger.error("ProtoMessage to JSON error:", e);
                throw new BusinessException(CommonEnum.DATA_CONVERSION_EXCEPTION);
            }
        }
        return null;
    }

   public static <T> T toJava2(Message sourceMessage, Class<T> clazz) {
        if (sourceMessage != null) {
            try {
                JsonFormat.TypeRegistry typeRegistry = JsonFormat.TypeRegistry.newBuilder().add(InsertRequest.getDescriptor()).build();
                JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(typeRegistry);
                JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry);
                String json = printer.print(sourceMessage);
                return null;
            } catch (InvalidProtocolBufferException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

当我想解除parse grpc消息到json,然后将

InvalidProtocolBufferException: Cannot find type for url 

i搜索smoe smoe答案丢弃,所以我更改了使用tojava2()它也会抛出相同的错误,或者,tojava2()代码有些变质吗?

我能做些什么?谢谢。

when i use proto3 to send gRPC message

my proto like this

service GraphService {
  rpc insertGraphData (InsertRequest) returns (google.protobuf.StringValue) {}
}

message InsertRequest {
  string tagName = 1;
  map<string, google.protobuf.Any> tagProperties = 2;
}

my client request entity like this

InsertRequest.newBuilder()
                .setTagName("facebook")
                .putTagProperties("userName", Any.newBuilder().setValue(ByteString.copyFrom("zzz", StandardCharsets.UTF_8)).build())
                .build()

my GraphRpcService like this

@GrpcService
@Slf4j
@RequiredArgsConstructor
public class GraphRpcService extends GraphServiceGrpc.GraphServiceImplBase {

    @Override
    public void insertGraphData(InsertRequest request, StreamObserver<StringValue> responseObserver) {
        StreamObserverDelegate.build(responseObserver).execute(()->{
       InsertRequest insertRequest = toJava(request, A.class);
//...
            return null;
        });
    }

    public static <T> T toJava(Message sourceMessage, Class<T> clazz) {
        if (sourceMessage != null) {
            try {
                return JSON.parseObject(JsonFormat.printer().includingDefaultValueFields().print(sourceMessage), clazz);
            } catch (InvalidProtocolBufferException e) {
                logger.error("ProtoMessage to JSON error:", e);
                throw new BusinessException(CommonEnum.DATA_CONVERSION_EXCEPTION);
            }
        }
        return null;
    }

   public static <T> T toJava2(Message sourceMessage, Class<T> clazz) {
        if (sourceMessage != null) {
            try {
                JsonFormat.TypeRegistry typeRegistry = JsonFormat.TypeRegistry.newBuilder().add(InsertRequest.getDescriptor()).build();
                JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(typeRegistry);
                JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry);
                String json = printer.print(sourceMessage);
                return null;
            } catch (InvalidProtocolBufferException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

when i want parse the gRPC Message to JSON then throw the

InvalidProtocolBufferException: Cannot find type for url 

i search smoe answer for the q,so i change method to use toJava2() it also throw the same err, or ,the toJava2() code has something woring?

what can i do? thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄离 2025-02-14 01:37:16

当您使用任何时,通常您需要any.pack()一条消息。请参阅 java生成代码 doc,doc,doc,和any.pack()为您设置type> typeurlprefix为您使用any.unpack()使用,以确定消息的类型重新包装。

在您的情况下,您可以直接使用any.newbuilder()。setValue(),并且不设置类型,因此any.unpack()不知道什么消息类型正在解开包装。

JSON打印机将消息转换为JSON。当它看到任何时,它也尝试解开它。因为它不知道类型,所以它无法做到,因此它抛出了无效的ProtocolBufferexception。请参阅 jsonformat.printer.print.print doc:

public java.lang.String Print(MessageorBuilder Message)
投掷无效的ProtocolBufferexception
抛出异常,如果消息中有未知类型。

When you use Any, normally you want to Any.pack() a Message into it. See the usage in the Java Generated Code doc, and the examples in the protobuf javadoc. Any.pack() sets the typeUrlPrefix for you, which is used by Any.unpack() to determine the type of the message you're unpacking.

In your case, you use Any.newBuilder().setValue() directly, and don't set the type, so Any.unpack() doesn't know what type of message is being unpacked.

JSON printer converts the message to JSON recursively. When it sees an Any, it attempts to unpack it too. Because it doesn't know the type, it can't do it, so it throws the InvalidProtocolBufferException. See JsonFormat.Printer.print doc:

public java.lang.String print(MessageOrBuilder message)
throws InvalidProtocolBufferException
Throws exceptions if there are unknown Any types in the message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文