Как отправить объекты разных классов в одном сообщении Json, чтобы их можно было десериализовать с помощью Gson?

1

Я хочу отправить сообщение (используя RabbitMQ, но я думаю, что это не важно). Текст сообщения находится в Json. Я хочу отправить информацию о двух классах в одном сообщении. На узле слушателя я хочу десериализовать сообщение с помощью Gson, чтобы снова получить мои объекты.

Один объект - простой объект, а второй - список простых объектов. Я не мог найти, как сериализовать два разных объекта в один Json, поэтому я упаковал их на карту и сделал сообщение из этой карты:

A a = new A();
ArrayList<B> bList = new ArrayList<B>();
bList.add(new B());
bList.add(new B());

HashMap<String, Object> map = new LinkedHashMap<>();
map.put("A", a);
map.put("B", bList);

String messageText = gson.toJson(map);

Если я сейчас хочу десериализовать сообщение:

HashMap<String, Object> sentItems = gson.fromJson(messageText, HashMap.class);
A a = (A) sentItems.get("A");
Collection<B> bList = (Collection<B>) sentItems.get("B");

Я получаю исключение из строки с get("A"):

com.google.gson.internal.StringMap cannot be cast to A.

Могу ли я исправить это или я должен следовать другому подходу, чтобы получить то, что я хочу?

Редактировать:

Ошибка такая же, если я сообщаю Gson типа, который я хочу использовать:

   Type type = new TypeToken<HashMap<String, Object>>() {}.getType();
    HashMap<String, Object> sentItems = gson.fromJson(argument.getValue(), type);
Теги:
gson

2 ответа

1
Лучший ответ

Я думаю, вам нужно сначала десериализовать "messageText" для JsonObject следующим образом:

JsonElement jsonElem = gson.fromJson(messageText, JsonElement.class);
JsonObject jsonObject = jsonElem.getAsJsonObject();

а затем извлекать элементы по их именам и десериализовать запрос по типу:

JsonElement jsonA = jsonObject.get("A");
A a = gson.fromJson(jsonA, A.class);

И для элемента списка:

JsonElement jsonBs = jsonObject.get("B");
Type bListType = new TypeToken<List<B>>(){}.getType();
List<B> dataSetIds = gson.fromJson(jsonBs, bListType);
1

Вам нужно создать один класс, который включает в себя две переменные из класса A а другой - это List of class B 'и десериализовать этот новый класс.

Class Parent{
    private A a;
    private ArrayList<B> bList;  

   //getter and setter method here.
}  

Во время Deserialize десериализуйте строку JSON в объект класса Parent, получите значение a и bList из метода getter, как показано ниже:

Parent p = gson.fromJson(messageText, Parent.class);  
A a = p.getA();  
ArrayList<B> bList = p.getBList();    

РЕДАКТИРОВАТЬ :
Имя переменной внутри класса Parent который является a и bList совпадает с ключом вашей map HashMap в другой стороне. В вашем случае это должно быть A вместо a и B вместо bList.

  • 0
    Я думаю, что вы правы, но я не хотел делать такой класс, потому что это не семантически оправдано.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню