数据由c#protobuf-net序列化并设置为redis, 现在我想获取数据并在java程序中反序列化,一切正常,期望日期时间字段,它们无法正确序列化。 在c#程序中,数据从实体序列化如下,并设置为redis
[Serializable]
[ProtoContract]
public class TestMsg
{
public TestMsg();
[ProtoMember(1)]
public string message { get; set; }
[ProtoMember(2)]
public DateTime UpdateTime { get; set; }
}
在我的java程序中,proto flie如下:
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?
}
答案 0 :(得分:1)
最近有一些新的“众所周知的”合同来描述时代。最好的办法是在java .proto中使用“timestamp”,并通过WellKnown
使用[ProtoMember]
数据格式注释DateTime成员。
要更简单地看到这一点:编写一个使用“timestamp”的.proto(无论如何你需要为java做),并通过https://protogen.marcgravell.com运行它以查看它输出的内容。以下是.proto的修改版本,因此您只需点击“生成”:https://protogen.marcgravell.com/#g38c45fbb1730d14bc4d560a13f61d2a3 - 如您所见,关键位是:
[global::ProtoBuf.ProtoMember(2,
DataFormat = global::ProtoBuf.DataFormat.WellKnown, IsRequired = true)]
public global::System.DateTime? UpdateTime { get; set; }
DataFormat = global::ProtoBuf.DataFormat.WellKnown
告诉它使用timestamp
表示法。同样,这会导致TimeSpan
使用众所周知的duration
表示法。
如果你有protobuf-net存储的预先存在的数据而没有众所周知的格式,那么你必须通过bcl.proto手动解码它;我很抱歉它不是那么简单,但是:它需要某种东西,而当时并不存在“众所周知”。