网上protobuf的资料不是很多,遇到问题比较费时间。说说可能会遇到的两个问题。
官方的说明:
https://developers.google.com/protocol-buffers/docs/proto3#json
JSON Mapping
Proto3 supports a canonical encoding in JSON, making it easier to share data between systems. The encoding is described on a type-by-type basis in the table below.
If a value is missing in the JSON-encoded data or if its value is null, it will be interpreted as the appropriate default value when parsed into a protocol buffer. If a field has the default value in the protocol buffer, it will be omitted in the JSON-encoded data by default to save space. An implementation may provide options to emit fields with default values in the JSON-encoded output.
1、protobuf buffer转换成json时候会把字段值是默认值的数据忽略,但它提供了方法可以解决这个问题。
首先添加依赖:
com.google.protobuf
protobuf-java-util
3.5.0
代码使用:
SomeProto.Builder builder = SomeProto.newBuilder();
SomeProto message = builder.build();
String json = com.google.protobuf.util.JsonFormat.printer().includingDefaultValueFields().print(message);
上面这段代码虽然没有给message设值,但因为使用了includingDefaultValueFields方法,所以会把所有的字段都输出。但如果没有使用includingDefaultValueFields方法就会只输出 {} 。
2、在json字符串转换成protobu的Message对象时,如果存在Message对象不存在的字段时会报InvalidProtocolBufferException,此时需要使用ignoringUnknownFields。
SomeProto.Builder builder = SomeProto.newBuilder();
Stirng json = some json data...
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
SomeProto proto = builder.build();
最后贡献将实体类转换成json再转成proto对象工具类:
import com.alibaba.fastjson.JSON;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.TextFormat.ParseException;
import com.google.protobuf.util.JsonFormat;
public class ProtobufUtils {
/**
* json数据转换为pb对象
*/
@SuppressWarnings("unchecked")
public static T json2pb(String json, Message.Builder builder) throws ParseException, InvalidProtocolBufferException {
if (builder == null) {
return null;
}
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
return (T) builder.build();
}
/**
* json数据转换为pb对象
*/
public static T json2pb(Object entity, Message.Builder builder) throws ParseException, InvalidProtocolBufferException {
if (builder == null || entity == null) {
return null;
}
return json2pb(JSON.toJSONString(entity), builder);
}
}
参考资料:https://github.com/HubSpot/jackson-datatype-protobuf/issues/12