Version: libprotoc 3.7.1
Language: Java 1.8.0_201
Operating system: Mac 10.14.6
I try to printAny, but get InvalidProtocolBufferException Exception in thread "main" com.google.protobuf.InvalidProtocolBufferException: Cannot find type for url: type.googleapis.com/api.DataEntity. All of the relevant codes are shown following.
package com.bees360.internal.ai.grpc.proto;
import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import io.gitlab.donespeak.protobuf.DataProto;
import io.gitlab.donespeak.protobuf.ResponseTestProto;
/**
* @author DoneSpeak
* @date 2019/08/29 10:22
*/
public class ResponseJsonTest {
public static void main(String[] args) throws InvalidProtocolBufferException {
DataProto.DataEntity data = DataProto.DataEntity.newBuilder().setData("data ...").build();
ResponseTestProto.ResponseJson.Builder builder = ResponseTestProto.ResponseJson.newBuilder();
builder.setData(Any.pack(data));
System.out.println(JsonFormat.printer().print(data));
ResponseTestProto.ResponseJson json = builder.build();
DataProto.DataEntity stageData = json.getData().unpack(DataProto.DataEntity.class);
System.out.println(json.getData().getTypeUrl());
// Exception
System.out.println(JsonFormat.printer().print(json.getData()));
System.out.println(stageData);
// Exception
System.out.println(JsonFormat.printer().print(json));
}
}
DataProto.proto
syntax = "proto3";
option java_package = "io.gitlab.donespeak.protobuf";
package api;
message DataEntity {
string data = 1;
}
ResponseTestProto.proto
syntax = "proto3";
import "google/protobuf/any.proto";
option java_package = "io.gitlab.donespeak.protobuf";
package api;
message ResponseJson {
int32 code = 1;
string msg = 2;
google.protobuf.Any data = 3;
}
Exception
{
"data": "data ..."
}
type.googleapis.com/api.DataEntity
Exception in thread "main" com.google.protobuf.InvalidProtocolBufferException: Cannot find type for url: type.googleapis.com/api.DataEntity
at com.google.protobuf.util.JsonFormat$PrinterImpl.printAny(JsonFormat.java:810)
at com.google.protobuf.util.JsonFormat$PrinterImpl.access$1000(JsonFormat.java:643)
at com.google.protobuf.util.JsonFormat$PrinterImpl$1.print(JsonFormat.java:713)
at com.google.protobuf.util.JsonFormat$PrinterImpl.print(JsonFormat.java:692)
at com.google.protobuf.util.JsonFormat$Printer.appendTo(JsonFormat.java:332)
at com.google.protobuf.util.JsonFormat$Printer.print(JsonFormat.java:342)
at com.bees360.internal.ai.grpc.proto.ResponseJsonTest.main(ResponseJsonTest.java:30)
Process finished with exit code 1
I solve the problem. A TypeRegistry for Any field is required.
A TypeRegistry is used to resolve Any messages in the JSON conversion. You must provide a TypeRegistry containing all message types used in Any message fields, or the JSON conversion will fail because data in Any message fields is unrecognizable. You don鈥檛 need to supply a TypeRegistry if you don鈥檛 use Any message fields.
JsonFormat.TypeRegistry typeRegistry = JsonFormat.TypeRegistry.newBuilder()
.add(DataProto.DataEntity.getDescriptor())
.build();
JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(typeRegistry);
System.out.println(printer.print(json.getData()));
System.out.println(printer.print(json));
Most helpful comment
I solve the problem. A
TypeRegistryforAnyfield is required.