【问题标题】:Deserialising string list in GSON?反序列化 GSON 中的字符串列表?
【发布时间】:2021-06-15 02:27:16
【问题描述】:

我正在尝试将字符串列表保存在 jsonobject 中并在加载时对其进行反序列化。当我保存列表时,我正在创建一个 JsonObject 并使用 GSON.toJson 将其添加为属性。我创建了一个 String arraylist 序列化器来序列化项目,当我检查我的 mongo 数据库时,它似乎保存为 jsonArray 但是当我尝试反序列化它时,它告诉我它不是 JsonArray。

这是我的代码:

订单对象:

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Getter
@Setter
@RequiredArgsConstructor
public class Order {

    private final UUID id;
    private final String table;

    private short numberOfPeople;
    private LocalDate timeOfOrder = LocalDate.now();

    private String staffInCharge = "";

    private List<String> order = new ArrayList<>();
    private String note = "";
}

@RequiredArgumentsConstructor 只是为我创建了一个构造函数,所以我不必做 public Order() 等

Serialise 和 Deserialise 类的导入:

import com.google.gson.*;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.oscar.orderbird.OrderBird;
import me.oscar.orderbird.gson.GsonUtil;
import me.oscar.orderbird.mongo.MongoUtils;
import me.oscar.orderbird.profile.food.Food;
import me.oscar.orderbird.profile.order.Order;
import me.oscar.orderbird.profile.staff.Staff;
import me.oscar.orderbird.profile.table.Table;
import org.bson.Document;

import java.util.*;

序列化:

        if (!this.orders.isEmpty()){
            JsonArray orderArray = new JsonArray();
            this.orders.values().forEach(order -> {
                JsonObject ordersObect = new JsonObject();
                ordersObect.addProperty("id", order.getId().toString());
                ordersObect.addProperty("name", order.getTable());
                ordersObect.addProperty("note", order.getNote());
                ordersObect.addProperty("numberOfPeople", order.getNumberOfPeople());
                ordersObect.addProperty("staffInCharge", order.getStaffInCharge());
                ordersObect.addProperty("orderItems", GsonUtil.GSON.toJson(order.getOrder()));
                orderArray.add(ordersObect);
            });
            document.put("orders", orderArray.toString());

        }

反序列化:

        if (document.containsKey("orders")) {
            if (document.get("orders") instanceof String) {
                JsonArray ordersArray = PARSER.parse(document.getString("orders")).getAsJsonArray();

                for (JsonElement jsonElement : ordersArray) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    try {
                        Order order = new Order(UUID.fromString(jsonObject.get("id").getAsString()), jsonObject.get("name").getAsString());
                        order.setNote(jsonObject.get("note").getAsString());
                        order.setNumberOfPeople(jsonObject.get("numberOfPeople").getAsShort());
                        order.setStaffInCharge(jsonObject.get("staffInCharge").getAsString());
                        order.setOrder(GsonUtil.GSON.fromJson(jsonObject.get("orderItems").getAsJsonObject(), ArrayList.class));
                        this.orders.put(jsonObject.get("name").getAsString(), order);

                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }

ArrayListAdapter:

package me.oscar.orderbird.gson.impl;

import com.google.gson.*;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class StringArrayAdapter implements JsonDeserializer<List<String>>, JsonSerializer<List<String>> {
    @Override
    public List<String> deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        JsonArray jsonArray = jsonElement.getAsJsonArray();
        List<String> values = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++){
            values.set(i, jsonArray.get(i).getAsJsonPrimitive().getAsString());
        }
        return values;
    }

    @Override
    public JsonElement serialize(List<String> stringList, Type type, JsonSerializationContext jsonSerializationContext) {
        JsonArray jsonArray = new JsonArray();
        for (String string : stringList) {
            jsonArray.add(new JsonPrimitive(string));
        }
        return jsonArray;
    }
}

当我尝试设置顺序时出现错误:

java.lang.IllegalStateException: Not a JSON Object: "[\n  \"Steak\"\n]"

【问题讨论】:

  • 你也可以添加Order对象类吗?
  • 另外请添加所有导入,这将有助于 SO 成员纠正问题
  • @dkb 我已经添加了你要求我添加的内容
  • 我还看到有像GsonUtilPARSERthis.orders.values() 这样的未知数 --> list/set/array 的 values() ?

标签: java json mongodb gson


【解决方案1】:

您的实施存在两个问题

  1. 从 Object 更改为 Document 时,您需要保留 orderItems 的属性类类型

改变

ordersObect.addProperty("orderItems", GsonUtil.GSON.toJson(order.getOrder()));

ordersObect.addProperty("orderItems", GSON.toJson(order.getOrder(), ArrayList.class));
  1. 从 Document 读取时,需要读取为相同的类类型

改变

GsonUtil.GSON.fromJson(jsonObject.get("orderItems").getAsJsonObject(), ArrayList.class)

GSON.fromJson(jsonObject.get("orderItems").getAsString(),ArrayList.class)

所以工作代码如下:

import com.Order;
import com.StringArrayAdapter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bson.Document;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

JsonParser PARSER = new JsonParser();
Gson GSON = new GsonBuilder()
        .registerTypeHierarchyAdapter(ArrayList.class, new StringArrayAdapter())
        .setPrettyPrinting()
        .serializeNulls()
        .create();
Document document = new Document();
Map<String, Order> orders = new HashMap<>();

for (int i = 0; i < 2; i++) {
    Order order = new Order(UUID.randomUUID(), "" + i);
    orders.put(order.getTable(), order);
}

// SO Post Code
if (!orders.isEmpty()) {
    JsonArray orderArray = new JsonArray();
    orders.values().forEach(order -> {
        JsonObject ordersObect = new JsonObject();
        ordersObect.addProperty("id", order.getId().toString());
        ordersObect.addProperty("name", order.getTable());
        ordersObect.addProperty("note", order.getNote());
        ordersObect.addProperty("numberOfPeople", order.getNumberOfPeople());
        ordersObect.addProperty("staffInCharge", order.getStaffInCharge());
        ordersObect.addProperty("orderItems", GSON.toJson(order.getOrder(), ArrayList.class));
        orderArray.add(ordersObect);
    });
    document.put("orders", orderArray.toString());
}

System.out.println("document: " + document);
Map<String, Order> readOrders = new HashMap<>();
if (document.containsKey("orders")) {
    if (document.get("orders") instanceof String) {
        JsonArray ordersArray = PARSER.parse(document.getString("orders")).getAsJsonArray();

        for (JsonElement jsonElement : ordersArray) {
            JsonObject jsonObject = jsonElement.getAsJsonObject();
            try {
                Order order = new Order(UUID.fromString(jsonObject.get("id").getAsString()), jsonObject.get("name").getAsString());
                order.setNote(jsonObject.get("note").getAsString());
                order.setNumberOfPeople(jsonObject.get("numberOfPeople").getAsShort());
                order.setStaffInCharge(jsonObject.get("staffInCharge").getAsString());
                order.setOrder((ArrayList<String>)GSON.fromJson(jsonObject.get("orderItems").getAsString(), ArrayList.class));
                readOrders.put(jsonObject.get("name").getAsString(), order);

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
System.out.println("Orders read : " + readOrders);

输出:

document: Document{{orders=[{"id":"e853617a-b516-4daf-ba6c-e5d731c556de","name":"0","note":"","numberOfPeople":0,"staffInCharge":"","orderItems":"[]"},{"id":"31004bbd-164d-4e64-b468-7021e1c21c39","name":"1","note":"","numberOfPeople":0,"staffInCharge":"","orderItems":"[]"}]}}
Orders read : {0=Order(id=e853617a-b516-4daf-ba6c-e5d731c556de, table=0, numberOfPeople=0, timeOfOrder=2021-06-16, staffInCharge=, order=[], note=), 1=Order(id=31004bbd-164d-4e64-b468-7021e1c21c39, table=1, numberOfPeople=0, timeOfOrder=2021-06-16, staffInCharge=, order=[], note=)}

【讨论】:

  • 这给了我错误: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:657) at java.util.ArrayList.set (ArrayList.java:448) 在 me.oscar.orderbird.gson.impl.StringArrayAdapter.deserialize(StringArrayAdapter.java:23) 在 me.oscar.orderbird.gson.impl.StringArrayAdapter.deserialize(StringArrayAdapter.java:9) 在com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69) 在 com.google.gson.Gson.fromJson(Gson.java:932) 在 me.oscar.orderbird.profile.Profile.fromDocument( Profile.java:164)
  • 你不应该得到那个错误,只需复制粘贴上面的代码并运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多