首页 > 解决方案 > 将 Json 文件反序列化为包含以对象为键的映射的 java 对象

问题描述

我正在努力寻找一种方法来读取需要放入地图的 json 文件。所以,我有一个类成分,它只包含一个字符串变量成分。在另一个名为 Recipe 的类中,我有一个 Map 将跟踪该特定配方所需的成分和数量,以及一个用于配方名称的 String。

public class Recipe implements Serializable{

    private String name;
    private Map<Ingredients,Integer> ingredientsList = new HashMap<>();

    public Recipe() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Map<Ingredients, Integer> getIngredientsList() {
        return ingredientsList;
    }

    public void setIngredientsList(Map<Ingredients, Integer> ingredientsList) {
        this.ingredientsList = ingredientsList;
    }

    @Override
    public String toString() {
        return "Recipe{" +
                "name='" + name + '\'' +
                ", ingredientsList=" + ingredientsList +
                '}';
    }
}

我有一个 testClass 包含两种方法,一种将我的配方写入 json 文件,另一种从同一个 json 文件中读取它

@Test
    public void writeToJsonFile(){
        Ingredients pasta = new Ingredients();
        pasta.setName("pasta");
        Ingredients bolognaise = new Ingredients();
        bolognaise.setName("bolognaise");

        Map<Ingredients,Integer>ingredientsIntegerMap = new HashMap<>();
        ingredientsIntegerMap.put(pasta,500);
        ingredientsIntegerMap.put(bolognaise,600);

        Recipe spaghetti = new Recipe();
        spaghetti.setName("spaghetti");
        spaghetti.setIngredientsList(ingredientsIntegerMap);

        Gson gson = new Gson();
        try {
            FileWriter writer = new FileWriter("src/test/resources/recipe1.json");
            writer.write(gson.toJson(spaghetti));
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void readFromJsonFile(){
        Gson gson = new Gson();
        try {
            BufferedReader buffer = new BufferedReader(new FileReader("src/test/resources/recipe1.json"));
            Recipe dish =gson.fromJson(buffer, Recipe.class);
            System.out.println(dish);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

现在我的问题如下,当我创建一个包含一些成分的食谱并将其保存到 json 填充时,我没有任何问题,一切正常,但是当我想将创建的 Jason 文件加载到食谱时,它不起作用。

这是我尝试读取 Json 文件时收到的错误消息

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 4 column 6 path $.ingredientsList.

这里是包含配方的 Created Json 文件

{
  "name":"spaghetti",
  "ingredientsList":{
    "Ingredients{name\u003d\u0027pasta\u0027}":500,
    "Ingredients{name\u003d\u0027bolognaise\u0027}":600
  }
}

当我删除它或用列表替换它时,由于配方类中的地图出现问题,一切正常,但我想使用地图。

有人可以帮助解决这个问题或推荐另一种方法来跟踪食谱的成分量

谢谢

标签: javaspringspring-bootspring-mvc

解决方案


将不包含任何唯一标识符的对象作为键放入 Map 中有点奇怪。也许将成分类更改为如下枚举会更好:

public enum Ingredients {
    PASTA,
    BOLOGNAISE
}

您的 JSON 将更改为:

{
  "name":"spaghetti",
  "ingredientsList":{
    "PASTA":500,
    "BOLOGNAISE":600
  }
}

或创建一个聚合对象,如:

public class IngredientQuantity {

    private Ingredient ingredient;
    private double quantity;

}

class Ingredient {
    private String name;
}

然后用一个简单的列表替换你的地图:

{
  "name": "spaghetti",
  "ingredientsList": [
    {
      "ingredient": {
        "name": "PASTA"
      },
      "quantity": 500
    },
    {
      "ingredient": {
        "name": "BOLOGNAISE"
      },
      "quantity": 600
    }
  ]
}

推荐阅读