0

I wanted to read a json file that looks like this:

{"default-values":[
    {"name":"cobblestone", "value":1},
    {"name":"dirt", "value":1},
    {"name":"sand", "value":1},

    {"name":"diamond", "value":8192},
    {"name":"redstone", "value":64},

    {"name":"iron_ingot", "value":256}
]}

What I want to do is create a method where someone types in JsonFileReader.getValue(String name) and have it return the value as an integer.

How would I go about this?

By the way, the error I am receiving is this:

java.lang.IllegalStateException: Expected a name but was BEGIN_OBJECT at line 1 column 2
David
  • 3
  • 1

2 Answers2

1

When using the following code I can read the JSON contents that you have provided. To read the file a simple InputStream is used (this version reads using the getClass().getResourceAsStream() approach but any type of InputStream such as URL.openConnection() or FileInputStream will work the same.

public class JsonFileReader {
    private Map<String, Integer> defaultValues = new HashMap<>();

    public static void main(String... args) throws IOException {
        final JsonFileReader reader = new JsonFileReader("/foo.json");
        System.out.println(reader.getValue("cobblestone")); // -> 1
    }

    public JsonFileReader(String filename) throws IOException {
        try (InputStream stream = getClass().getResourceAsStream(filename)) {
            ObjectMapper mapper = new ObjectMapper();
            final JsonNode result = mapper.readTree(stream);

            for (JsonNode defaultValue : result.path("default-values")) {
                defaultValues.put(
                    defaultValue.get("name").asText(), 
                    defaultValue.get("value").asInt());
            }
        }
    }

    public Integer getValue(String name) {
        return defaultValues.get(name);
    }
}

JsonNode and ObjectMapper are part of the Jackson library. Jackson is a suite of data-processing tools for Java that includes a JSON parsing and generation library. Simply add the following to your pom.xml (or similar) to get access to the proper libs:

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.3.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.3.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.3.3</version>
    </dependency>
</dependencies>

EDIT:* The OP indicated that they did not use Java 7+. The Java 5/6-version of the try statement looks like the very verbose code sample below.

public JsonFileReader(String filename) throws IOException {
    InputStream stream = null;
    try {
        stream = getClass().getResourceAsStream(filename);
        ObjectMapper mapper = new ObjectMapper();
        final JsonNode result = mapper.readTree(stream);

        for (JsonNode defaultValue : result.path("default-values")) {
            defaultValues.put(
                    defaultValue.get("name").asText(),
                    defaultValue.get("value").asInt());
        }
    } finally {
        if (stream != null) {
            stream.close();
        }
    }
}
wassgren
  • 18,651
  • 6
  • 63
  • 77
  • This should work great, thanks :) – David Dec 27 '14 at 14:39
  • Just one thing though, are JsonNode and ObjectMapper part of a specific API? Because my IDE doesn't know of these classes. @wassgren – David Dec 27 '14 at 14:42
  • Yes, `JsonNode` and `ObjectMapper` are part of the [Jackson library](https://github.com/FasterXML/jackson). I have updated the answer to reflect this. – wassgren Dec 27 '14 at 15:01
  • try-with-resources is not supported at this language level is an error I am now receiving – David Dec 28 '14 at 08:56
  • Which version of Java are you using? try-with-resources comes with Java 7. – wassgren Dec 28 '14 at 08:58
  • So, If you are using Java 8 it try-with-resources is definitely supported. But, your project may be configured for other versions of Java even if it runs on Java 8. E.g. if you have a Maven project check [this out](http://stackoverflow.com/questions/16723533/modify-pom-xml-to-include-jdk-compiler-version). – wassgren Dec 28 '14 at 10:27
  • I checked my IDE and it is definitely configured to Java 8 – David Dec 28 '14 at 10:31
  • Alos, whenever I run the second method it returns a nullpointerexception – David Dec 28 '14 at 10:54
  • @David - I have updated the example once more with a fully functional constructor that is based on a non try-with-resources construct. I hope this will help! – wassgren Dec 28 '14 at 11:01
  • The method works great, thanks :) However, when I change the getValue() method to static, I do this because I can't reference it any where in the code if it isn't static, I am receiving a NullPointerException. The Json file exists and I have specified the directory correctly. I'm not really sure what I should do to fix this. I'm not really an expert at this coding thing :P – David Dec 28 '14 at 11:14
  • Do you know any way to fix this ? – David Dec 28 '14 at 14:45
0

You may want to look into the google-gson library for doing Json manipulation/reads in Java. It is Apache licensed.

https://code.google.com/p/google-gson/

Bajal
  • 5,487
  • 3
  • 20
  • 25