Help with advanced Jackson usage

236 views
Skip to first unread message

John Gentilin

unread,
Jan 15, 2012, 3:24:56 AM1/15/12
to BatchFB
I know this is not a BatchFB issue but it is fairly related so I
wanted to try and document it here
to help with documentation of batchfb in more complex cases.

For the /photos or /EVENTID/photos query, the raw result below is
returned and I am trying to map that
into JSON Jackson objects.. The following complex class are defined as
follows, any other classes are
simple JSON mappings according to the sample data...

According to the documentation, I define my routine to access the
Event data as follows

Batcher batcher = new FacebookBatcher(token);

PagedLater<List<Photo>> photos =
batcher.graph(fbEventID+ "/photos", new
TypeReference<List<Photo(){});

Which produces a syntax error in Java , for me the line
batcher.graph(fbEventID+ "/photos", new
TypeReference<List<Photo(){});
is missing a ">" following the docs, but a ">" in any other
location is still a fail...

Thank youohn Gentilin

// NOTE: missing java classes are simple Jackson map classes.

public class Photo
{
public long id;
@JsonProperty("from")
public Owner from;
public String picture;
public String source;
public int height;
public int width;
@JsonProperty("images")
public List<Image> images;
public String link; // "link": "http://www.facebook.com/photo.php?
pid=131637&id=100003282514152",
public String icon; // "icon": "http://static.ak.fbcdn.net/rsrc.php/
v1/yz/r/StEh3RhPvjk.gif",
public String created_time; // "created_time":
"2012-01-13T23:37:30+0000",
public String position; // "position": 9,
public String updated_time; // "updated_time":
"2012-01-13T23:37:32+0000",
@JsonProperty("comments")
Paged<Later<Comment>> comments;
}

public class Comment
{
public long id;
@JsonProperty("from")
public Owner from;
public String message;
public Boolean can_remove;
public String created_time;
}

public class Owner
{
public String name = ""; //"name": "Friends of the Alameda Animal
Shelter (FAAS)",
public String category = ""; // Used in Events "category": "Local
business",
public long id = 0; // "id": "188792315991"
}



sample data
/**
* Sample Data
*
*
* "data": [
{
"id": "129050813881002",
"from": {
"name": "Pic Rollr",
"id": "100003282514152"
},
"picture": "http://photos-e.ak.fbcdn.net/hphotos-ak-
ash4/396521_129050813881002_100003282514152_131637_1376871324_s.jpg",
"source": "http://a5.sphotos.ak.fbcdn.net/hphotos-ak-ash4/
s720x720/396521_129050813881002_100003282514152_131637_1376871324_n.jpg",
"height": 540,
"width": 720,
"images": [
{
"height": 540,
"width": 720,
"source": "http://a5.sphotos.ak.fbcdn.net/hphotos-ak-ash4/
s720x720/396521_129050813881002_100003282514152_131637_1376871324_n.jpg"
},
{
"height": 135,
"width": 180,
"source": "http://photos-e.ak.fbcdn.net/hphotos-ak-
ash4/396521_129050813881002_100003282514152_131637_1376871324_a.jpg"
},
{
"height": 97,
"width": 130,
"source": "http://photos-e.ak.fbcdn.net/hphotos-ak-
ash4/396521_129050813881002_100003282514152_131637_1376871324_s.jpg"
},
{
"height": 56,
"width": 75,
"source": "http://photos-e.ak.fbcdn.net/hphotos-ak-
ash4/396521_129050813881002_100003282514152_131637_1376871324_t.jpg"
}
],
"link": "http://www.facebook.com/photo.php?
pid=131637&id=100003282514152",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yz/r/
StEh3RhPvjk.gif",
"created_time": "2012-01-13T23:37:30+0000",
"position": 9,
"updated_time": "2012-01-13T23:37:32+0000",
"comments": {
"data": [
{
"id": "129050813881002_43778",
"from": {
"name": "Pic Rollr",
"id": "100003282514152"
},
"message": "comment1",
"can_remove": true,
"created_time": "2012-01-13T23:39:06+0000"
}
],
"paging": {
"next": "https://graph.facebook.com/129050813881002/comments?
method=GET&metadata=true&format=json&callback=___GraphExplorerAsyncCallback___&access_token=AAACEdEose0cBAM5bC7lod7xcJHbD7QHwjqhB8cXsxAV8WaOKZBoPZBnCz1OXc80bzb8L7njWZBHolR5nny6tPKijWAhZBiytmpQGIiuqUtmTNZAZBEDCUb&limit=25&offset=25&__after_id=129050813881002_43778"
}
}
},

*/

Jeff Schnitzer

unread,
Jan 15, 2012, 11:59:16 AM1/15/12
to bat...@googlegroups.com
I'm not quite sure what you want to do here, but note that
PagedLater<T> extends Later<List<T>>. So creating a
PagedLater<List<T>> is actually a Later<List<List<T>>, almost
certainly not what you had in mind.

The best way of getting photos is like this:

PagedLater<Photo> photos = batcher.paged(fbEventID+"/photos", Photo.class);

For the "under the covers" view of the Jackson magic, this is
effectively the same as:

Later<Paged<Photo>> photos = batcher.graph(fbEventID+"/photos", new
TypeReference<Paged<Photo>>(){});

TypeReference is one of the clever ways Jackson works around erasure
in Java generics (boo!). I wrote up how this works here:

http://code.google.com/p/batchfb/wiki/UserGuide#Generics_and_TypeReference

Jeff

John Gentilin

unread,
Jan 16, 2012, 9:42:18 PM1/16/12
to BatchFB
Hi Jeff,

What I am trying to achieve, is that I make a request to /photos which
returns a a list of JSON objects
with a prev & next URL as part of the descriptive data. Once I make
the request, I will have a PagedLater<Photo>
object that I can iterate on, if I come to the end of the current data
set, I can use paging to fetch the next page
to iterate on, or go backwards. The inside each photo, the same will
occur for the comments or any other Paged List data set.

From your comment below, I implemented the code
PagedLater<Photo> photoRequest =
batcher.graph(fbEventID+ "/photos", Photo.class);

produces a compiler error, "can not convert from GraphRequest<Photo>
to PagedLater<Photo>"

So I used the code in the BatchFB docs, (Note: the example in the user
manual has a syntax error)
Later<List<Photo>> photoRequest =
batcher.graph(fbEventID+ "/photos", new
TypeReference<List<Photo>>(){});

which produces the following error when the get is processed..
Can not deserialize instance of java.util.ArrayList out of
START_OBJECT token
at [Source: N/A; line: -1, column: -1]

Later I changed the code to be
Later<Paged<Photo>> photoRequest =
batcher.graph("/" + fbEventID+ "/photos", new
TypeReference<Paged<Photo>>(){});
Paged<Photo> photos = photoRequest.get();

Which seemed to work different / better, in that it was complaining
about the internal paged object comments.

Can not construct instance of com.googlecode.batchfb.PagedLater,
problem: abstract types can only be instantiated with additional type
information
at [Source: N/A; line: -1, column: -1] (through reference chain:
com.googlecode.batchfb.type.Paged["data"]-
>com.CloudTvApps.PicRollr.shared.FBObjects.Photo["comments"])

My Photo class is defined as
public class Photo
{
public long id;
@JsonProperty("from")
public Owner from;
public String picture;
public String source;
public int height;
public int width;
@JsonProperty("images")
public List<Image> images;
public String link; /
public String icon; //
public String created_time; //
public String position;
public String updated_time; //
@JsonProperty("comments")
PagedLater<Comment> comments;

and my comments class is defined as
public long id;
@JsonProperty("from")
public Owner from;
public String message;
public Boolean can_remove;
public String created_time;


What am I doing wrong.. ??

Thank you
-John G

On Jan 15, 8:59 am, Jeff Schnitzer <j...@infohazard.org> wrote:
> I'm not quite sure what you want to do here, but note that
> PagedLater<T> extends Later<List<T>>.  So creating a
> PagedLater<List<T>> is actually a Later<List<List<T>>, almost
> certainly not what you had in mind.
>
> The best way of getting photos is like this:
>
> PagedLater<Photo> photos = batcher.paged(fbEventID+"/photos", Photo.class);
>
> For the "under the covers" view of the Jackson magic, this is
> effectively the same as:
>
> Later<Paged<Photo>> photos = batcher.graph(fbEventID+"/photos", new
> TypeReference<Paged<Photo>>(){});
>
> TypeReference is one of the clever ways Jackson works around erasure
> in Java generics (boo!).  I wrote up how this works here:
>
> http://code.google.com/p/batchfb/wiki/UserGuide#Generics_and_TypeRefe...

John Gentilin

unread,
Jan 17, 2012, 12:36:26 AM1/17/12
to BatchFB
Ok, figured it out.. The Comments element is paged, but I did not
notice that it only has a single
data: element, which is a list of comments. So in Class Photo I have
an field defined as
@JsonProperty("comments")
public Paged<Comment> comments;

The the Comment class defines the array of comments
public class Comment {
@JsonProperty("data")
public List<CommentData> data;
}

The comment data is the actual data..
public class CommentData {
public String id;
@JsonProperty("from")
public Owner from;
public String message;
public Boolean can_remove;
public String created_time;
}

The JSON Data
"comments": {
"data": [ {
"id": "129050813881002_43778",
"from": {
"name": "Pic Rollr",
"id": "100003282514152"
},
"message": "comment1",
"can_remove": true,
"created_time": "2012-01-13T23:39:06+0000"
}
],
"paging": {
"next": "https://graph.facebook.com/129050813881002/comments?
method=GET&metadata=true&format=json...."
}
}

On Jan 15, 8:59 am, Jeff Schnitzer <j...@infohazard.org> wrote:
> I'm not quite sure what you want to do here, but note that
> PagedLater<T> extends Later<List<T>>.  So creating a
> PagedLater<List<T>> is actually a Later<List<List<T>>, almost
> certainly not what you had in mind.
>
> The best way of getting photos is like this:
>
> PagedLater<Photo> photos = batcher.paged(fbEventID+"/photos", Photo.class);
>
> For the "under the covers" view of the Jackson magic, this is
> effectively the same as:
>
> Later<Paged<Photo>> photos = batcher.graph(fbEventID+"/photos", new
> TypeReference<Paged<Photo>>(){});
>
> TypeReference is one of the clever ways Jackson works around erasure
> in Java generics (boo!).  I wrote up how this works here:
>
> http://code.google.com/p/batchfb/wiki/UserGuide#Generics_and_TypeRefe...

Jeff Schnitzer

unread,
Jan 17, 2012, 12:52:25 AM1/17/12
to bat...@googlegroups.com
I'm afraid you still have me confused. However, I added an example of
reading /me/photos to the test cases. See the photos() method here:

http://code.google.com/p/batchfb/source/browse/trunk/src-test/com/googlecode/batchfb/test/PagedTests.java#119

Jeff

John Gentilin

unread,
Jan 17, 2012, 1:19:41 AM1/17/12
to BatchFB
Hi Jeff,

So that worked too, I think previously I was either defining the
Comment element
as PagedLater or List, it wasn't till the very end that I defined it
as Paged but by then
I had broken out the Comment class as Comment and CommentData...

Thank you for the feedback..

-John Gentilin


On Jan 16, 9:52 pm, Jeff Schnitzer <j...@infohazard.org> wrote:
> I'm afraid you still have me confused.  However, I added an example of
> reading /me/photos to the test cases.  See the photos() method here:
>
> http://code.google.com/p/batchfb/source/browse/trunk/src-test/com/goo...
Reply all
Reply to author
Forward
0 new messages