Deserializing object List from fql response - Can not deserialize instance of FacebookAlbums out of START_OBJECT token

420 views
Skip to first unread message

Florrie O.

unread,
Oct 13, 2013, 8:02:32 AM10/13/13
to bat...@googlegroups.com
Hi everybody.

I want to get all albums for a given user using FQL with the following code:

  Batcher batcher = new FacebookBatcher(token);
       
        String query = "select name, like_info.like_count, photo_count,link,location, created from album where owner=%s";
        HashMap<Integer, FacebookPage> results = cf.loadFbFile("C:\\mydata.ods");
        int number = 0;
        for (int i : results.keySet()) {
            FacebookPage fp = results.get(i);
            String id = (String)fp.getId();
            int index = fp.getUniInt();
            String name = fp.getUniversity();
            University u = new University();
            u.setName(name);
            if (!id.equals("")) {
                number++;
                String newquery = String.format(query, id);
                Later<FacebookAlbums> albums = batcher.queryFirst(newquery, FacebookAlbums.class);
                fbReq.put(u, albums);
            }
        }
 
        for (University u : fbReq.keySet()) {
            String name = u.getName();
            System.out.println(name);
            FacebookAlbums albums = fbReq.get(u).get();        
            for(FacebookAlbum fa : albums){
                System.out.println(fa.getName());
                System.out.println(fa.getDescription());            
            }
        }

As it's a list of albums, Later<FacebookAlbums> albums = batcher.queryFirst(newquery, FacebookAlbum.class); won't work because of type erasure. So I tried to use a custom class extending an ArrayList for my purposes but with no avail:

public class FacebookAlbums extends ArrayList<FacebookAlbum> {
}
 
the FacebookAlbum class:

public class FacebookAlbum {
    private String name;
    private int photo_count;
    private String link;
    private String location;
    private String description;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public int getPhoto_count() {
        return photo_count;
    }
  
    public void setPhoto_count(int photo_count) {
        this.photo_count = photo_count;
    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
 
but Jackson cannot deserialize the FacebookAlbums class. I'm quite confused on what to do now.

Thanks.

Jeff Schnitzer

unread,
Oct 13, 2013, 11:37:04 PM10/13/13
to bat...@googlegroups.com
It's not immediately obvious to me why Jackson wouldn't deserialize your class; what error do you get?

Jeff


--
You received this message because you are subscribed to the Google Groups "BatchFB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to batchfb+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Florrie O.

unread,
Oct 14, 2013, 7:29:47 AM10/14/13
to bat...@googlegroups.com, je...@infohazard.org
First of all, sorry if I answered you privately, Jeff. I'm still not much aware of the interface.

Here's the error trace:

ott 14, 2013 12:54:29 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [FacebookAlbums] in context with path [/Tesi2] threw exception
java.lang.IllegalArgumentException: Can not deserialize instance of FacebookAlbums out of START_OBJECT token
 at [Source: N/A; line: -1, column: -1]
    at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.java:2502)
    at org.codehaus.jackson.map.ObjectMapper.convertValue(ObjectMapper.java:2482)
    at com.googlecode.batchfb.impl.MapperWrapper.convert(MapperWrapper.java:53)
    at com.googlecode.batchfb.impl.MapperWrapper.convert(MapperWrapper.java:35)
    at com.googlecode.batchfb.util.LaterWrapper.get(LaterWrapper.java:45)
    at com.googlecode.batchfb.util.LaterWrapper.get(LaterWrapper.java:45)
    at com.googlecode.batchfb.util.FirstElementLater.get(FirstElementLater.java:51)
    at GetFacebookAlbums.doGet(GetFacebookAlbums.java:52)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of FacebookAlbums out of START_OBJECT token
 at [Source: N/A; line: -1, column: -1]
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:219)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:212)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:246)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:204)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:194)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:194)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
    at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315)
    at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.java:2498)
    ... 28 more

At line 52 I try to fetch the array of albums from the Facebook API:
List<FacebookAlbum> albums = fbReq.get(u).get();

Jeff Schnitzer

unread,
Oct 14, 2013, 10:52:19 AM10/14/13
to bat...@googlegroups.com
You're trying to deserialize to an array object (ie []), but the json structure you're getting is an object (ie {}).  Perhaps try hitting the graph endpoint (the non-batch version) directly and see what the actual result to expect is.

Jeff

Florrie O.

unread,
Oct 14, 2013, 11:54:44 AM10/14/13
to bat...@googlegroups.com, je...@infohazard.org
I get an object with the property "data".

{
  "data": [
    {
      "name": "Timeline Photos",
      "photo_count": 71,
      "created": 1351586108
    },
    {
      "name": "Cover Photos",
      "photo_count": 25,
      "created": 1331283230
    },
    {
      "name": "Profile Pictures",
      "photo_count": 25,
      "created": 1329316815
    },
    {
      "name": "Premio di laurea \"Natalina & Marco\"",
      "photo_count": 2,
      "created": 1380184383
    },
...]
}

I tried to change the FacebookAlbums accordingly:

public class FacebookAlbums {
    public List<FacebookAlbum> data;

    public List<FacebookAlbum> getData() {
        return data;
    }

    public void setData(List<FacebookAlbum> data) {
        this.data = data;
    }
}

But then when I try to reach the list of albums (either by albums.getData() or by albums.data) all I get is a null value.

Jeff Schnitzer

unread,
Oct 15, 2013, 2:33:34 AM10/15/13
to bat...@googlegroups.com
Check out the Paged and PagedLater classes, and the Batcher.paged() method. Facebook has a special "paged" format for many responses that includes "data", "previous", and "next" fields.

Jeff

Florrie O.

unread,
Oct 15, 2013, 5:35:30 AM10/15/13
to bat...@googlegroups.com, je...@infohazard.org
I used this already, the problem with this approach is I have to subsequently fetch data from the /likes and /comments connections, while with FQL I could do all in a single call. Guess I can't just use FQL in this case :/

Jeff Schnitzer

unread,
Oct 15, 2013, 10:56:55 AM10/15/13
to bat...@googlegroups.com
You can, just use the Paged object (or your own structure) to deserialize the result.

Jeff
Reply all
Reply to author
Forward
0 new messages