【问题标题】:Importing json that was serialized by JSON is failing导入由 JSON 序列化的 json 失败
【发布时间】:2017-11-10 07:16:07
【问题描述】:

所以我有一个包含一些字段的对象...

protected String name;
protected String relativePathAndFileName;
protected DateTime next_Run;
protected ArrayList<String> hosts;

像这样序列化为 JSON:

public void serialize(){
    Gson gson = Converters.registerDateTime(new GsonBuilder()).setPrettyPrinting().create();
    String json = gson.toJson(this);

    try {
        FileWriter writer = new FileWriter(this.relativePathAndFileName);
        writer.write (json);
        writer.close();
    } catch (IOException e) {
        logger.error("Error while trying to write myAlert to json: ", e);
    }
}

稍后当我需要读取这个 json 文件时,我会尝试这样做:

try {
        for (File f : alertConfigFiles) {
            Gson gson = new Gson();
            JsonReader reader = new JsonReader(new FileReader(f));
            Type type = new TypeToken<Map<String, String>>(){}.getType();
            Map<String, String> myMap = gson.fromJson(reader, type);
            Alert tempAlert = new Alert(myMap);
            myAlerts.add(tempAlert);
            logger.debug("Imported: " + f.toString());
        }

我得到的错误是:

Unhandled exception when trying to import config files: 
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 28 column 13 path $.

文件中的 JSON 的作用是:

 {
 "name": "Logs Per Host - past 24 hours",
 "relativePathAndFileName": "./Elk-Reporting/Alerts/logs_per_host24h.json",
 "next_Run": "2017-06-07T22:24:56.682-04:00",
 "hosts": [
    "app-12c",
    "app1-18",
    "wp-01",
    "app-02",
    "wp-02",
    "cent-04",
    "app-06",
    "app-05"
  ]
  }

当它尝试导入主机的 ArrayList 时似乎很窒息,但它能够毫无问题地将它们写出来。

任何人都可以就如何让我的导入正常工作提供一些建议吗?

【问题讨论】:

  • 您正在写入文件?如果有,里面是什么?
  • @AlexFerretti -- 更新问题以包含 json。

标签: java json arraylist gson


【解决方案1】:

这两行似乎是问题所在:

Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson(reader, type);

您序列化某个特定类的对象。然后将其反序列化为 type。但是您的 JSON 不适合 Map。最好这样做,这样您就可以使用自己的类。

YourClass myMap = gson.fromJson(reader, YourClass.class);

如果您想使用这种方法,您可能需要更改您的 Java 类以保存字符串数组,而不是字符串的 ArrayList。

也许this page 对您有所帮助。尤其是第一种情况适合您的情况。

另一个选项是自定义解串器,如 here 所述。

【讨论】:

  • 我试了一下,但这似乎也没有成功 -- 尝试 { for (File f : alertConfigFiles) { Gson gson = new Gson(); JsonReader reader = new JsonReader(new FileReader(f));警报 tempAlert = gson.fromJson(reader, Alert.class); myAlerts.add(tempAlert); logger.debug("导入的:" + f.toString());尝试导入配置文件时导致与上述相同的异常未处理异常:com.google.gson.JsonSyntaxException: java.lang.IllegalStateException
【解决方案2】:

尽量保持简单。使用地图等,是有问题的一种方式。 这是反序列化/序列化的工作代码:

package com.rizze.beans.labs.sof;

import static org.junit.Assert.assertTrue;

import org.junit.Test;

import com.google.gson.Gson;

public class SOFGson {


    public String json = "{  \"name\": \"Logs Per Host - past 24 hours\", \"relativePathAndFileName\": \"./Elk-Reporting/Alerts/logs_per_host24h.json\", \"next_Run\": \"2017-06-07T22:24:56.682-04:00\", \"hosts\": [ \"bos-qa-app-12c\", \"bos-qa-app1-18\", \"bos-qa-wp-01\", \"bos-lt-app-02\", \"bos-qa-wp-02\", \"bos-dev-cent-04.americanwell.com\", \"bos-qa-app-06\", \"bos-qa-app-05\" ]}";

    public class MyObj{
        protected String name;
        protected String relativePathAndFileName;
        protected String next_Run;
        protected String[] hosts;
    }

    @Test
    public void test() {

        Gson gson = new Gson();
        MyObj obj = gson.fromJson(json, MyObj.class);
        assertTrue(obj!=null);
        assertTrue(obj.hosts.length==8);
        System.out.println(gson.toJson(obj));


    }

}

这是 gist 中的类:https://gist.github.com/jeorfevre/7b32a96d4ddc4af68e40bf95f63f2c26

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    相关资源
    最近更新 更多