简体   繁体   中英

Using JSON libraries for parsing JSON to JavaObject

I'm using the IntelliJ Idea and Play Framework with Java. I send a request to the server and get a response in JSON format. But the response is huge and I actually need only one line from it. All the others can be ignored. How can I use this line further in my program as a JavaObject , and how can I ignore the other lines?

For ignoring other lines, I tried something like this:

.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

but it gives me an error saying:

cannot find symbol symbol: DeserializationFeature

As I know, I can use Jackson library in Play Framework. I'm not sure if I used it correctly.

Here is my code:

import play.libs.Json;
import org.codehaus.jackson.map.ObjectMapper;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core;
...
StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

        return ok(response.toString());
    }

Here's the response in JSON format: https://pastebin.com/kh7pGiN5 .

And here's the build.sbt from the Framework, as I am not sure I used the libraries correctly:

// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "2.9.8"

// https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl
libraryDependencies += "org.codehaus.jackson" % "jackson-mapper-asl" % "1.9.13"

// https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl
libraryDependencies += "org.codehaus.jackson" % "jackson-core-asl" % "1.9.13"

// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-annotations" % "2.9.8"

// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.8"

First of all you should use only FasterXML dependencies. Remove all codehaus dependencies. When you read JSON and you need only one or few elements you can read JSON as JsonNode and traverse it as a tree. To speed up traversing you can use paths : /response/GeoObjectCollection/featureMember to find featureMember array and /GeoObject/metaDataProperty/GeocoderMetaData/Address/Components to find Components array in each element of featureMember . See below app to find out all details:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(jsonFile);
        GeoObjectWalker walker = new GeoObjectWalker(root);

        List<String> countries = Arrays.asList("Germany", "United States of America", "Austria", "Belgium");
        countries.forEach(country -> {
            final String message = "'%s' has first province: '%s'";
            System.out.println(String.format(message, country, walker.findProvinceForCountry(country).orElse("'not found'")));
        });
    }
}

class GeoObjectWalker {

    private final JsonNode root;

    public GeoObjectWalker(JsonNode root) {
        this.root = root;
    }

    public Optional<String> findProvinceForCountry(String country) {
        // find featureMember array
        JsonNode featureMembers = root.at("/response/GeoObjectCollection/featureMember");
        if (featureMembers.isMissingNode()) {
            return Optional.empty();
        }

        for (int i = 0; i < featureMembers.size(); i++) {
            JsonNode featureMember = featureMembers.get(i);
            // find Components array
            JsonNode components = featureMember.at("/GeoObject/metaDataProperty/GeocoderMetaData/Address/Components");
            if (components.isMissingNode()) {
                continue;
            }

            if (componentsArrayContains(components, "country", country)) {
                Optional<String> province = findNameForKind(components, "province");
                if (province.isPresent()) {
                    return province;
                }
            }
        }

        return Optional.empty();
    }

    private boolean componentsArrayContains(JsonNode array, String kind, String name) {
        for (int i = 0; i < array.size(); i++) {
            JsonNode node = array.get(i);
            if (node.get("kind").asText().equals(kind) && node.get("name").asText().equals(name)) {
                return true;
            }
        }

        return false;
    }

    private Optional<String> findNameForKind(JsonNode array, String kind) {
        for (int i = 0; i < array.size(); i++) {
            JsonNode node = array.get(i);
            if (node.get("kind").asText().equals(kind)) {
                return Optional.of(node.get("name").asText());
            }
        }

        return Optional.empty();
    }
}

Above code prints:

'Germany' has first province: 'Bayern'
'United States of America' has first province: 'South Carolina'
'Austria' has first province: 'Oberösterreich'
'Belgium' has first province: 'Vlaams Brabant'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM