1

So I have an object with some fields...

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

Which gets serialized to JSON like this:

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);
    }
}

Later when I need to read in this json file, I try to do so like this:

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());
        }

The error that I'm getting is:

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 $.

The JSON inside the file is something to the effect of:

 {
 "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"
  ]
  }

It seems to be choking when it tries to import the ArrayList of hosts, but it was able to write them out without issues.

Can anyone offer some advice on how to get my import working without issues?

A_Elric
  • 3,508
  • 13
  • 52
  • 85

2 Answers2

0

Those two lines seem to be the problem:

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

You serialize your object of some specific class. You then deserialize it to type. But your JSON does not fit into a Map. Better do it like this, so you can use your own class.

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

If you want to use this approach, you might want to change your Java class to hold an array of strings instead of an ArrayList of strings.

Maybe this page helps you a bit. Especially the first case fits your situation.

Another option is a custom Deserialzer as described here.

Markus
  • 2,071
  • 4
  • 22
  • 44
  • I gave this a shot, but this doesn't seem to work out either -- try { for (File f : alertConfigFiles) { Gson gson = new Gson(); JsonReader reader = new JsonReader(new FileReader(f)); Alert tempAlert = gson.fromJson(reader, Alert.class); myAlerts.add(tempAlert); logger.debug("Imported: " + f.toString()); } resulted in the same exception as above Unhandled exception when trying to import config files: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException – A_Elric Jun 08 '17 at 15:26
0

try to keep it simple. Using maps and so on, is a way to have issues. Here is a working code to deserialise / serialise :

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));


    }

}

here is the class in gist : https://gist.github.com/jeorfevre/7b32a96d4ddc4af68e40bf95f63f2c26

jeorfevre
  • 2,286
  • 1
  • 17
  • 27