Преобразование динамического сообщения protobuf, возвращаемого вызовом gRPC, в JSON или аналогичный объект

Я делаю вызов gRPC на сервер, используя отражение, которое возвращает динамическое сообщение в качестве ответного сообщения. Теперь, хотя этот объект похож на вложенный объект, его структура немного отличается от JSON. Это делает выборку значений на основе полей, таких как

someObject.get(someField) 

трудный. Один из способов — преобразовать это сообщение в объект, а затем получить нужные значения. Любые предложения по разбору здесь?

Это возвращаемый класс:

com.google.protobuf.DynamicMessage

Но, хотя это выглядит как вложенный JSON, мы не можем получать значения на основе полей.

Чтобы иметь общее представление о схеме, вот как выглядит ответ:

field1 {
  key1: "value1"
}
field2 {
  key1: "value1"
  key2: value2
  key3 {
    netsed_key_1: "nested_val_1"
    netsed_key_2: "nested_val_2"
  }
  key4 {
    netsed_key_1: "nested_val_1"
    netsed_key_2: "nested_val_2"
  }
}

Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

Community 25.01.2023 21:55
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуй это:

FieldDescriptor fieldDescriptor = message.getDescriptorForType().findFieldByName("someField");
Object value = message.getField(fieldDescriptor);

Чтобы получить список всех полей:

Map<Descriptors.FieldDescriptor, Object> allFields = message.getAllFields();

Чтобы получить вложенное значение, сделайте следующее:

Message subMessage =
    (Message)message.getField(
        message.getDescriptorForType().findFieldByName("field3"));
Message subSubMessage =
    (Message)subMessage.getField(
    subMessage.getDescriptorForType().findFieldByName("key3"));
String subSubSubMessage veryNestedString =
    (String)subSubMessage.getField(
    subSubMessage.getDescriptorForType().findFieldByName("netsed_key_1"));

Привет, Джон, спасибо за ответ. Я добавил образец схемы в основной вопрос, чтобы мы могли получить представление о схеме, на которую мы ссылаемся. message.getAllFields() просто возвращает поля первого уровня, а не вложенные поля, есть ли какие-либо предложения, как мы собираемся ссылаться на них. Кроме того, message.getDescriptorForType().findFieldByName("someField"); дает нулевой указатель, так как карта имеет ключи в формате FieldDesriptor, а здесь мы даем строку.

GlidingSwords997 26.01.2023 14:38

Привет, Джон, я обновил комментарий и вопрос, не могли бы вы поделиться еще немного света?

GlidingSwords997 26.01.2023 14:41

Я смог разрешить NPE, но все еще не смог получить значения на основе вложенных ключей.

GlidingSwords997 26.01.2023 14:50

Я получаю сообщение об ошибке неизменяемого списка при приведении типа к Message: Failed to read message., причина = java.lang.ClassCastException: java.util.Collections$UnmodifiedRandomAccessList не может быть приведен к com.google.protobuf.Message

GlidingSwords997 27.01.2023 06:31

В режиме отладки, без приведения, можете ли вы проверить типы элементов в UnmodifiedRandomAccessList?

John Williams 27.01.2023 10:36

Если поле, к которому вы обращаетесь, является повторяющимся полем, вам нужно будет использовать message.getRepeatedField вместо message.getField. Это относится к field3?

San P 30.01.2023 22:19

Другие вопросы по теме