1

What I want to do is , when I navigate to:

http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[your_api_key]&q=Toy+Story+3&page_limit=1

It returns a JSON response. I want to convert it into Java Object. I am using the Jackson library. This is my data class:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown=true)
public class  Aman
{

public static class Title
{
    private String title;

    public String getTitle(){ return title; }

    public String setTitle(String s){ return title = s; }
}

private int id;
private int year;
private int total;

public void SetId(int i){ id = i; }

public void SetYear(int y){ year = y; }

public void SetTotal(int t){ total =t; }

public int GetId()
{
    return id;
}

public int GetYear()
{
    return year;
}

public int GetTotal()
{
    return total;
}
@Override
public String toString()
{
    return "Movies[total=" +total + "id=" + id + "year=" + year + "]";
}
}

and my mapper class:

import java.io.File;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import java.net.*;

public class Movie
{
     public static void main(String[] args) throws MalformedURLException, URISyntaxException, IOException {
 Aman a = new Aman();
 ObjectMapper mapper = new ObjectMapper();
 try
 {
 URL RT = new URL("http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=gzscv4f8zqse75w94mmp37zz&q=Toy+Story+3&page_limit=1").toURI().toURL();
 a = mapper.readValue(RT, Aman.class);
    }catch(MalformedURLException u)
    {
        u.printStackTrace();
    }catch(URISyntaxException s)
    {
        s.printStackTrace();
    }catch(IOException i)
    {
        i.printStackTrace();
    }

}
}

It shows me no output whatsoever. Am I doing something wrong?

Franz Kafka
  • 10,623
  • 20
  • 93
  • 149
Aman Grover
  • 1,621
  • 1
  • 21
  • 41
  • You don't have any code to output anything if your read succeeds. After you read the value do something like `System.out.println( a.GetId());`, or override `toString()` in your Aman class and `System.out.println( a );` – digitaljoel Apr 15 '13 at 15:37
  • @digitaljoel I edited the code , you can see it in the question, but still no output. – Aman Grover Apr 15 '13 at 15:54

1 Answers1

4

You have a mix of basic Java programming and JSON mapping errors. First of all, remember to follow lower camel case naming conventions when defining your Java classes. Not only is it a best practice but more importantly, several tools and libraries will not work if you do not follow this pattern (Jackson included).

As far as your JSON mapping errors, the most important thing to keep in mind when mapping JSON to Java objects is that JSON data is effectively a map. It associates keys with values, where the values can be primitives, objects, or arrays (collection). So, given a JSON structure you have to look at the structure of each keys value, then decide wether that value should be represented in Java as a primitive, an object, or as an array of either. No shortcuts to this, you will learn by experience. Here is an example:

{
    "total": 1,                          // maps to primitive, integer
    "movies": [                          // '[' marks the beginning of an array/collection
        {                                // '{' marks the beginning of an object
            "id": "770672122",           // maps to primitive, string
            "title": "Toy Story 3",
            "year": 2010,
            "mpaa_rating": "G",
            "runtime": 103,
            "release_dates": {          // each array object also contains another object
                "theater": "2010-06-18",
                "dvd": "2010-11-02"
            }
        }
    ]
}

When mapping the example JSON above, you need to define a root object that matches the outermost {. Lets call this root object a MovieResponse.

public class MovieResponse {
}

Now, walking down the JSON data, we start to map over all the JSON attributes to Java properties:

@JsonIgnoreProperties(ignoreUnknown = true)
public class MovieResponse {
    private Integer total;        // map from '"total": 1'
    private List<Movie> movies;   // map from '"movies": [', remember, its a collection
}

Simple right? But of course, we also need to define a structure for the Movie class. Once again, walking the JSON:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Movie {
    private String id;            // map from '"id": "770672122"'
    private String title;         // map from '"title": "Toy Story 3"'
    private Integer year;
    @JsonProperty("mpaa_rating")
    private String mpaaRating;
    private Integer runtime;
    @JsonProperty("release_dates")
    private Release released;     // another object mapping!
}

And finally, map the inner-most object that represents release dates:

public class Release {
    private String theater;
    private String dvd;
}

Thats it, very straightforward. Note the use of @JsonProperty in the Movie class. It allows you to map an attribute from your JSON to a property in Java, with a different name. Also note that constructors/setters/getters were omitted from each of the classes above, for brevity. In your real code you would add them in. Finally, you would map the example JSON to the Java MovieResponse class using the following code:

MovieResponse response = new ObjectMapper().readValue(json, MovieResponse.class);
Perception
  • 79,279
  • 19
  • 185
  • 195
  • well , all I can say is , this is the complete explanation I was looking for , I Know I have asked some dumb questions , but I am just a beginner. Thanks a lot. – Aman Grover Apr 15 '13 at 16:24
  • what's the use of Listmovies , when I have to make a new class Movie and map it's values there? – Aman Grover Apr 15 '13 at 17:14
  • @AmanGrover - because both in the example I used and the data you are getting back from RT, the JSON can contain ***multiple*** movies per response. Remember - JSON array maps to Java collection. – Perception Apr 15 '13 at 17:26
  • how can I map the list movies? – Aman Grover Apr 15 '13 at 17:29
  • @AmanGrover - the example shows exactly how to map a list of movies from the given JSON. Please read through it again. – Perception Apr 15 '13 at 17:33
  • I am really confused with the Movie class you made. Then what will be the use of Listmovies. As I am getting another exception: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "movies" (Class MovieResponse), not marked as ignorable at [Source: http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=gzscv4f8zqse75w94mmp37zz&q=Toy+Story+3&page_limit=1; line: 31, column: 22] (through reference chain: MovieResponse["movies"]) – Aman Grover Apr 15 '13 at 18:38
  • The classes I showed are for example only, you need to flesh them out based off the response you are getting from the RT API. As it is, you need to add `@JsonIgnoreProperties(unknown=true)` to the top of the `Movie` and `MovieResponse` class, if you don't map all the JSON attributes to Java properties. – Perception Apr 15 '13 at 18:58
  • Does the class Movie represent the movies array in json data in your code? – Aman Grover Apr 18 '13 at 19:40
  • The `movies` array in the JSON data is mapped to a collection on the `MovieResponse` object. ***Each*** item in the collection is represented by a `Movie` class. – Perception Apr 18 '13 at 19:53
  • @Perception Help me with this please - Why do I get an error when instead of `MovieResponse response = new ObjectMapper().readValue(json, MovieResponse.class);`, I use `MovieResponse response = gson.fromJson(json, MovieResponse.class);` – paradocslover Jun 15 '21 at 10:16