【问题标题】:Gson writes to the file, but can't deserializeGson 写入文件,但无法反序列化
【发布时间】:2020-05-05 14:19:01
【问题描述】:

已解决。

我有一个关于 Gson 对象的写/读列表的问题。我有一个产品类:

public class Product {
    private String name;
    private double price;
    private int quantity;
    public Product(String name, double price, int quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
......

然后我有一个 ProductList 类:

public class ProductMenu {
    public List<Product> productList;
    public ProductMenu() {
        productList = new ArrayList<>();
    }
......

我在另一个类中初始化我的产品列表:

public class ShoppingOperations {
    ProductUpdater import = new ProductUpdaterFromJson();
    private ProductMenu shopItems = import.importProducts();
.....

我想做的是在构造函数中初始化我的产品列表,如下所示:

public class ProductMenu {
    public List<Product> productList;
    public ProductMenu() {
        ProductUpdater getList = new ProductUpdaterFromJson();
        productList = getList.importProducts();
    }
......

这是我将对象列表写入 .json 文件的方法:

public class ProductUpdaterFromJson implements ProductUpdater {
    public final static String PATH = "src\\shop\\products\\promenu.json5";
    @Override
    public void updateWarehouseData(ProductMenu shopItems) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        try {
            Writer writer = new FileWriter(PATH);
            gson.toJson(shopItems, writer);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            System.out.println("file not found");
            e.printStackTrace();
        }
    }

.json 文件看起来像这样。它是用 Gson 生成的:

{
  "productList": [
    {
      "name": "Cheese",
      "price": 1.37,
      "quantity": 6
    },
    {
      "name": "Milk",
      "price": 1.16,
      "quantity": 7
    },
    {
      "name": "Milka",
      "price": 0.66,
      "quantity": 2
    },
    {
      "name": "Potatoes",
      "price": 0.7,
      "quantity": 7
    },
    {
      "name": "Tea",
      "price": 2.1,
      "quantity": 4
    }
  ]
}

但我在尝试读取此文件时遇到错误。构造函数需要 List,但我的文件编写器写入 ProductMenu(它与产品的列表相同),但我有这个错误 - 线程“main”com.google.gson.JsonSyntaxException 中的异常:java.lang.IllegalStateException:预期 BEGIN_ARRAY 但是是STRING 在第 1 行第 1 列路径 $ 这是从 .json 文件中读取的方法:

public final static String PATH = "src\\shop\\products\\promenu.json5";
public List<Product> importProducts2() {
    Gson gson = new Gson();
    Type userListType = new TypeToken<ArrayList<Product>>(){}.getType();
    return gson.fromJson(PATH, userListType);
}

我该如何解决这个问题。 Writer 写入,但无法读取文件并使用产品初始化列表。

我在会员的帮助下找到的解决方案:

public class ProductUpdaterFromJson implements ProductUpdater {
    public final static String PATH = "src\\shop\\products\\promenu.json5";

    @Override
    public void updateWarehouseData(ProductMenu shopItems) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        try {
            Writer writer = new FileWriter(PATH);
            gson.toJson(shopItems.productList, writer);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            System.out.println("file not found");
            e.printStackTrace();
        }
    }

    public List<Product> importProducts() {
        Gson gson = new Gson();
        List<Product> list = null;
        try {
            Reader reader = new FileReader(PATH);
            Type userListType = new TypeToken<ArrayList<Product>>(){}.getType();
            list =  gson.fromJson(reader, userListType);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return list;
    }
}

还有构造函数:

public class ProductMenu {

    public List<Product> productList;

    public ProductMenu() {
        ProductUpdater listFromJson = new ProductUpdaterFromJson();
        productList = listFromJson.importProducts();
    }

【问题讨论】:

  • 你解析的字符串src\\shop\\products\\promenu.json5不是文件的内容
  • 正如@Jens 已经提到的,gson.fromJson(PATH, userListType); PATH 是一个字符串,表示路径,而不是来自该路径的文件内容。请看how to parse JSON file with GSON
  • @Jens 谢谢,我将其更改为:public List&lt;Product&gt; importProducts2() { Gson gson = new Gson(); List&lt;Product&gt; im = null; try { Reader reader = new FileReader(PATH); Type userListType = new TypeToken&lt;ArrayList&lt;Product&gt;&gt;(){}.getType(); im = gson.fromJson(reader, userListType); } catch (FileNotFoundException e) { e.printStackTrace(); } return im; } 现在问题是:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处是 BEGIN_OBJECT
  • 你写了一个对象(ProductMenu)并想读一个列表(ArrayList)
  • 我做了更改,建议保存为普通产品列表:public void updateWarehouseData(ProductMenu shopItems) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); try { Writer writer = new FileWriter(PATH); gson.toJson(shopItems.productList, writer); writer.flush(); writer.close(); } catch (IOException e) { System.out.println("file not found"); e.printStackTrace(); } }

标签: java json gson


【解决方案1】:

尝试在序列化中使用 ProductMenu

public List<Product> importProducts2() {
    Gson gson = new Gson();
    ProductMenu productMenu = gson.fromJson(new InputStreamReader(...), ProductMenu.class);
    return productMenu.productList
}

或者序列化普通列表

gson.toJson(shopItems.productList, writer);

【讨论】:

  • 它显示:线程“main”java.lang.NullPointerException中的异常
  • 我像你写的那样对普通列表进行了序列化。 json 文件看起来没问题。但尝试阅读时仍然出错。
  • 是的。空指针。我使用相同的路径来编写 .json 文件,它可以工作。
  • java.base/java.io.Reader.(Reader.java:167) 处的 java.base/java.io.Reader 处的线程“main”java.lang.NullPointerException 中的异常。 io.InputStreamReader.(InputStreamReader.java:72) at shop.products.ProductUpdaterFromJson.importProducts2(ProductUpdaterFromJson.java:42) 我现在正在使用您建议的代码:ProductMenu productMenu = gson. fromJson(new InputStreamReader(getClass().getResourceAsStream(PATH)), ProductMenu.class);
  • 试试gson.fromJson(new FileReader(PATH), ProductMenu.class); 使用getResourceAsStream需要不同的路径格式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
相关资源
最近更新 更多