ProtoBuf 使用JsonFormat.printToString(Message)打出的Json非法问题(以逗号开头的json)

在实际使用protobuf传递消息的时候,如果本地pb文件与远端pb文件不一致,会导致本地将消息序列化为json字符串的时候,打印unknowFields的时候出现数字key,并且在该field可识别的字段都为空的时候,会出现以逗号开头,接着数字key的json片段,导致该json整体非法无法被其他json框架识别.
如下面的例子:

{“site”: {, “12”: [“c4-5”]}, “14”: [2]}

加粗的地方即为以(,)开始的非法json片段.

在protobuf-java-format-1.2 的版本中,

protected static void print(Message message, JsonGenerator generator) throws IOException {
		for (Iterator<Map.Entry<FieldDescriptor, Object>> iter = message.getAllFields().entrySet().iterator(); iter
				.hasNext();) {
			Map.Entry<FieldDescriptor, Object> field = iter.next();
			printField(field.getKey(), field.getValue(), generator);
			if (iter.hasNext()) {
				generator.print(",");
			}
		}
		if (message.getUnknownFields().asMap().size() > 0)
			generator.print(", ");
		printUnknownFields(message.getUnknownFields(), generator);
	}

在打印未知字段之前,会打印出问题所在的(,),基于结果可想而知上面那段代码没有执行进去,即该对象除了未知字段有值以外,其他已知字段都没有,导致打印出非法json片段.在这里完整copy jar包里的JsonFormat类的代码,修改下print方法为:

protected static void print(Message message, JsonGenerator generator) throws IOException {
		boolean hasSetBefore = !message.getAllFields().entrySet().isEmpty();
		for (Iterator<Map.Entry<FieldDescriptor, Object>> iter = message.getAllFields().entrySet().iterator(); iter
				.hasNext();) {
			Map.Entry<FieldDescriptor, Object> field = iter.next();
			printField(field.getKey(), field.getValue(), generator);
			if (iter.hasNext()) {
				generator.print(",");
			}
		}
		if (hasSetBefore && message.getUnknownFields().asMap().size() > 0)
			generator.print(", ");
		printUnknownFields(message.getUnknownFields(), generator);
	}

在打印未知字段之前先判断现有已知字段是否都有值就行.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值