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);
	}

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

    原文作者:Rezar_
    原文地址: https://blog.csdn.net/sinat_29131797/article/details/105561892
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞