2

I'm trying to read this json file:

{
  "username": "someusername",
  "password": "12345678",
  "ipAddresses": {
    "2015-09-12": "127.0.0.1"
  }
}

Using this class to store the info:

private final class SavedPlayer {
    private final String username;
    private final String password;
    private final HashMap<LocalDate, String> ipAddresses;

    private SavedPlayer(
            String username, String password,
            HashMap<LocalDate, String> ipAddresses
    ) {
        this.username = username;
        this.password = password;
        this.ipAddresses = ipAddresses;
    }
}

And this part of the code throws an exception:

private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
SavedPlayer savedPlayer = GSON.fromJson(reader, SavedPlayer.class);

This is the thrown exception:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 5 column 17

How can I read this stored HashMap properly?

Edit: it works fine when i use <String, String> instead of <LocalDate, String>

3
  • If you make your HashMap in Java a HashMap<String, String> ipAddresses; does that fix the issue. Commented Sep 12, 2015 at 18:37
  • Works fine with <String, String> How can I still use <LocalDate, String> ? @bhspencer Commented Sep 12, 2015 at 19:03
  • @user2997204 Please check this post for GSON deserializing key-value to custom object. Commented Sep 12, 2015 at 19:12

3 Answers 3

1

Gson allows you to register your own custom serializers and deserializers. This is done by defining two parts:

Json Serialiers: Need to define custom serialization for an object Json Deserializers: Needed to define custom deserialization for a type Instance Creators: Not needed if no-args constructor is available or a deserializer is registered

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(LocalDate.class, new MyDeserializer());

registerTypeAdapter call checks if the type adapter implements more than one of these interfaces and register it for all of them.

for more information check gson-user-guide

Here is an example of how to write a custom deserialize for LocalDate

public class LocalDateJsonDeserializer implements JsonDeserializer<LocalDate> {    
      public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
          throws JsonParseException {
        return new LocalDate(json.getAsJsonPrimitive().getAsString());
      }
}

and use this line for creating GSON.

final static Gson GSON = new GsonBuilder().registerTypeAdapter(LocalDate.class, new LocalDateJsonDeserializer()).setPrettyPrinting().create();
Sign up to request clarification or add additional context in comments.

Comments

1

To bind JSON to LocalDate, you either have to write your custom serializer/deserialzer by implementing JsonDeserializer and registering with GSON using method registerTypeAdapter(), or you can use existing library for that: https://github.com/gkopff/gson-javatime-serialisers

Comments

0

Edit: You can find GSON deserializing key-value to custom object.


I tried the code you pasted with Gson 2.4 library. Also I converted the LocalDate to String. It is working absolutely fine.

public class SavedPlayer {
  private final String username;
  private final String password;
  private final HashMap<String, String> ipAddresses;

  private SavedPlayer(
      String username, String password,
      HashMap<String, String> ipAddresses
  ) {
    this.username = username;
    this.password = password;
    this.ipAddresses = ipAddresses;
  }

  public static void main(String[] args) throws FileNotFoundException {
    final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
    SavedPlayer savedPlayer = GSON.fromJson("{\n" +
        "  \"username\": \"someusername\",\n" +
        "  \"password\": \"12345678\",\n" +
        "  \"ipAddresses\": {\n" +
        "    \"2015-09-12\": \"127.0.0.1\"\n" +
        "  }\n" +
        "}", SavedPlayer.class);
    System.out.println(savedPlayer.username);
    System.out.println(savedPlayer.password);
    for (Map.Entry entry : savedPlayer.ipAddresses.entrySet()) {
      System.out.println("Key: " + entry.getKey() + "\tValue: " + entry.getValue());
    }
  }
}

Output:
someusername
12345678
Key: 2015-09-12 Value: 127.0.0.1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.