4

Would it be possible if someone could help me parse this json result. I have retrieved the result as a string

{"query":{"latitude":39.9889,"longitude":-82.8118},"timestamp":1310252291.861,"address":{"geometry":{"coordinates":[-82.81168367358264,39.9887910986731],"type":"Point"},"properties":{"address":"284 Macdougal Ln","distance":"0.02","postcode":"43004","city":"Columbus","county":"Franklin","province":"OH","country":"US"},"type":"Feature"}}

4 Answers 4

8

Jackson. Simple and intuitive to use. For me the best available. Start out with Simple Data Binding, it will throw everything it finds in Maps and Lists.

Like this:

ObjectMapper mapper = new ObjectMapper();
Map<String,Object> yourData = mapper.readValue(new File("yourdata.json"), Map.class);

That's all that's needed.

A good and quick introduction can be found here

And a full working example with your actual data:

import java.io.IOException;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;

public class Main {

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Map<?,?> rootAsMap = mapper.readValue(
                "{\"query\":{\"latitude\":39.9889,\"longitude\":-82.8118},\"timestamp\":1310252291.861,\"address\":{\"geometry\":{\"coordinates\":[-82.81168367358264,39.9887910986731],\"type\":\"Point\"},\"properties\":{\"address\":\"284 Macdougal Ln\",\"distance\":\"0.02\",\"postcode\":\"43004\",\"city\":\"Columbus\",\"county\":\"Franklin\",\"province\":\"OH\",\"country\":\"US\"},\"type\":\"Feature\"}}".getBytes(),
                Map.class);
        System.out.println(rootAsMap);
        Map query = (Map) rootAsMap.get("query");
        Map address = (Map) rootAsMap.get("address");
        Map addressProperties = (Map) address.get("properties");
        String county = (String) addressProperties.get("county");
        System.out.println("County is " + county);
    }

}

Now, this whole Map juggling also illustrates Bozho's point pretty well, using full binding (by creating a Java class that reflects the content of the JSON data) will work better in the end.

Sign up to request clarification or add additional context in comments.

3 Comments

Jackson is the only JSON-to/from-Java library I've seen that will deserialize any Json object of arbitrary complexity to a Map<String, Object> in just one simple line. Note that the casts to Map and String would be unnecessary if a Map<String, Object> parameterized type reference were used with the call to readValue. TypeReference mapType = new TypeReference<Map<String, Object>>(){}; Map<String, Object> result = new ObjectMapper().readValue(new File("input.json"), mapType);
@fvu This example was the one I was looking for. It did what I need it to do. Thanks a lot. I run this through a for loop with a new string like the one above. So I need to escape the " on the new string as well?
Never mind I had a stupid moment when I saw this, LOL. I got everything working thanks a lot guys for all your help.
3

The two best options that I know of are:

Using them is a matter of calling one method of the mapper. But remember that since Java is statically-typed, you may have to create an object that has the required structure. (You don't have to, but it feels more natural)

6 Comments

No you don't, see the link to Jackson simple databinding in my reply.
@fvu you don't have to, yeah, but it is better in most cases, imo
I guess I'm a little confused on the best route to take. It seems like every result is different. Im thinking I need clarification of what an object and arrays are what each result contains.
@bozho the sheer simplicity of simple databinding makes it easy for people to get started, "upgrading" to full databinding is imo something that will come naturally.
@flu can you point to some good examples or tutorials? I just need a jump start. :)
|
2

From http://www.json.org, under the Java section:

Pick your poison

1 Comment

This is a sampling of the worst JSON-to/from-Java libraries, right?
1

With Jackson, following is the approach I'd take. Since the coordinates in the JSON come in two different formats -- sometimes an object, sometimes an array -- the solution is mildly complicated with necessary custom deserialization processing.

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.ObjectCodec;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.module.SimpleModule;
import org.codehaus.jackson.node.ArrayNode;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
    mapper.registerModule(
      new SimpleModule("CoordinatesDeserializer", Version.unknownVersion())
        .addDeserializer(Coordinates.class, new CoordinatesDeserializer()));

    Result result = mapper.readValue(new File("input.json"), Result.class);
    System.out.println(mapper.writeValueAsString(result));
  }
}

class CoordinatesDeserializer extends JsonDeserializer<Coordinates>
{
  @Override
  public Coordinates deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
  {
    ObjectCodec codec = jp.getCodec();
    JsonNode node = codec.readTree(jp);
    if (node.isObject())
    {
      ObjectMapper mapper = new ObjectMapper();
      mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
      return mapper.readValue(node, Coordinates.class);
    }
    // else it's an array
    ArrayNode array = (ArrayNode) node;
    Coordinates coordinates = new Coordinates();
    coordinates.latitude = codec.treeToValue(array.get(0), BigDecimal.class);
    coordinates.latitude = codec.treeToValue(array.get(1), BigDecimal.class);
    return coordinates;
  }
}

class Result
{
  Coordinates query;
  BigDecimal timestamp;
  Address address;
}

class Coordinates
{
  BigDecimal latitude;
  BigDecimal longitude;
}

class Address
{
  String type;
  Geometry geometry;
  AddressDetails properties;
}

class Geometry
{
  String type;
  Coordinates coordinates;
}

class AddressDetails
{
  String address;
  BigDecimal distance;
  String postcode;
  String city;
  String county;
  String province;
  String country;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.