Jackson和REST Android注释:反序列化JSON对象数组

时间:2013-08-09 16:06:55

标签: rest jackson android-annotations

我有一个REST服务,它返回如下所示的数据:

[
    { bookmark object json here },
    { bookmark object json here },
    { bookmark object json here },
    ...
]

我的REST客户端类看起来像这样:

@Rest(rootUrl = Constants.ApiConfig.API_ROOT, converters = {MappingJackson2HttpMessageConverter.class})
public interface RestApiClient {
    @Get("/bookmark/read?id={identifier}")
    public BookmarkList getBookmarks(String identifier);
}

BookmarkList如下所示:

public class BookmarkList {
    List<Bookmark> bookmarks;

    @JsonValue
    public List<Bookmark> getBookmarks() {
        return bookmarks;
    }

    @JsonCreator
    public void BookmarkList(@NotNull List<Bookmark> bookmarks) {
        this.bookmarks = bookmarks;
    }
}

但是,当我使用此设置时,我收到以下错误:

  

无法读取JSON:无法从START_ARRAY标记中反序列化com.whatever.entity.BookmarkList的实例

我想要的是类似于https://github.com/excilys/androidannotations/wiki/Rest-API#get的EventList示例,但这对我来说似乎并不适用。

有没有办法让这个工作?

2 个答案:

答案 0 :(得分:2)

何......我们必须更新这部分文档。包装器解决方案有效,但不适合API。

如果您正在查看@Get("url") MyReturnedType testService()的生成代码,您应该会看到以下内容:

return restTemplate.exchange(rootUrl.concat("url"), //
    HttpMethod.GET, //
    null, //
    MyReturnedType.class, //
    urlVariables)//
  .getBody();

返回的类被注入为exchange调用的参数。在泛型集合的情况下(如List<MyReturnedType>),由于交换方法的返回类型检查,我们无法注入List.class

但是,您应该能够在@Rest带注释的方法中使用这个小技巧:

public class BookmarkList extends List<Bookmark> {
}

答案 1 :(得分:0)

我想我误解了https://github.com/excilys/androidannotations/wiki/Rest-API#get的例子。我认为在该示例中数组仍然必须包装在JSON对象中(如果它们包含示例JSON数据,那就太好了)。

我正在连接的服务所返回的数据不会返回包含数组的对象,因此,我将REST客户端更改为如下所示:

@Rest(rootUrl = Constants.ApiConfig.API_ROOT, converters = {MappingJackson2HttpMessageConverter.class})
public interface RestApiClient {
    @Get("/bookmark/read?id={identifier}")
    public ArrayNode getBookmarks(String identifier);
}

我在另一个类中编写了一个方法来迭代ArrayNode并构建书签:

public List<Bookmark> getBookmarks(Content content) {
    ArrayList<Bookmark> bookmarks = new ArrayList<Bookmark>();
    ArrayNode bookmarksData = apiClient.getBookmarks(content.getAcid());

    for(JsonNode bookmarkData : bookmarksData) {
        Bookmark bookmark = objectMapper.convertValue(bookmarkData, Bookmark.class);
        bookmarks.add(bookmark);
    }
    return bookmarks;
}

所以它不那么方便(我不得不自己编写更多的代码),但我让它工作了。