Protobuf игнорирует значения bool и ints по умолчанию
Я преобразую файл JSON в строку, а затем строка преобразуется в файл Proto3.
Вот файл json:
{ "a": false,
"b": 0
}
Вот как я конвертирую мой файл json в строку:
String json =Files.lines(Paths.get(filePath)).collect(Collectors.joining());
Вот как я конвертирую свою строку в файл proto3:
JsonFormat.parser().ignoringUnknownFields().merge(json,messageBuilder);
MyProto proto = messageBuilder.build();
В моем json есть логические поля и поля int, значения некоторых из них должны быть значениями по умолчанию (false для логического значения и 0 для int).
Когда я десериализирую вышеуказанный файл в java-файл proto3, оба вышеуказанных поля игнорируются, и мой json становится пустым, даже если я явно установил значения (как вы можете видеть в приведенном выше файле json).
Я знаю, что proto3 игнорирует значения по умолчанию при десериализации / сериализации, однако есть ли способ не игнорировать поля, которые явно установлены, даже если они являются значениями по умолчанию?
3 ответа
Использовал proto2 вместо proto3 . Proto2 имеет такое поведение - если поле задано явно, хотя оно является значением поля по умолчанию, оно сериализуется и десериализуется.
Нет, руководство по языку Protobuf прямо заявляет, что это невозможно:
Обратите внимание, что для скалярных полей сообщения, после того, как сообщение проанализировано, нет никакого способа сказать, было ли для поля явно установлено значение по умолчанию (например, было ли булево значение установлено в false) или просто не установлено вообще: вы должны иметь это в будьте осторожны при определении типов сообщений. Например, не используйте логическое значение, которое включает некоторое поведение при значении false, если вы не хотите, чтобы это поведение также происходило по умолчанию. Также обратите внимание, что если для поля скалярного сообщения установлено значение по умолчанию, значение не будет сериализовано в проводной сети.
Если вы действительно должны знать, было ли установлено значение по умолчанию явно или нет, вы должны закодировать эту информацию в отдельном поле.
Начиная с версии 3.15, protobuf3 позволяет явно отслеживать присутствие черезключевое слово.
То есть, учитывая
message MyProto
{
optional int32 field = 1;
}
протокол сгенерируетhas_field()
/hasField()
(в зависимости от языка) для проверки того, было ли поле установлено явно.
(Примечание: поля protobuf3 по умолчанию являются необязательными,optional
ключевое слово делает их «обнуляемыми»).
Другой вариант — использовать « хорошо известные » сообщения-обертки:
import "google/protobuf/wrappers.proto"
message MyProto
{
Int32Value field = 1;
}
Однако их использование устарело .