jqtrip
jqtrip

Reputation: 11

how to deserialized data which is serialized by protobuf-net in a java program

the data is serialized by c# protobuf-net and set to the redis, now i want to get the data and deserialize it in a java program,everything is ok expect the datetime fields ,they can not be serialized properly. in c# program the data is serialized from the entity as follow,and set to redis

[Serializable]
[ProtoContract]
public class TestMsg 
{
    public TestMsg();
    [ProtoMember(1)]
    public string message { get; set; }
    [ProtoMember(2)]
    public DateTime UpdateTime { get; set; }
}

in my java program,the proto flie is as follow:

syntax = "proto2";
option java_outer_classname = "TestMsgEntity";
message TestMsg {
    required string Message = 1;//
    required string UpdateTime = 2;// it can not be deserialized properly.if I change is to long,then i get zero .
}

//java code

byte[]  byteArrayRedis  = provider.getbyte("keyname"); //get the data from redis

ByteArrayInputStream baiContent = new ByteArrayInputStream(byteArrayRedis);
try {
        TestMsgEntity.TestMsg msg = TestMsgEntity.TestMsg.parseFrom(baiContent);
        String message = msg.getMessage (); //it is ok
        String lastUpdate =msg.getLastUpdateTime();//how can i get the value? 
    }

Upvotes: 1

Views: 513

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062512

Recently there are new "well known" contracts for describing times. Your best bet is to use "timestamp" in the java .proto, and annotate the DateTime member with the WellKnown data format via the [ProtoMember].

To see this more simply: write a .proto (which you need to do for java anyway) that uses "timestamp", and run it through https://protogen.marcgravell.com to see what it outputs. Here's a modified version of your .proto so you can just click "Generate": https://protogen.marcgravell.com/#g38c45fbb1730d14bc4d560a13f61d2a3 - as you can see, the key bit is this:

[global::ProtoBuf.ProtoMember(2,
    DataFormat = global::ProtoBuf.DataFormat.WellKnown, IsRequired = true)]
public global::System.DateTime? UpdateTime { get; set; }

It is the DataFormat = global::ProtoBuf.DataFormat.WellKnown that tells it to use timestamp notation. Similarly, this will cause a TimeSpan to use the well-known duration notation.


If you have preexisting data stored by protobuf-net without the well-known format, then you'll have to decode it manually via bcl.proto; I apologise that it isn't as simple as it could be, but: it needed to be something, and nothing "well known" existed at the time.

Upvotes: 1

Related Questions