4

为我与(4.0.3b)Google App Engine一起使用的 Android 应用程序提供后端服务。Objectify

在后端我有一个简单的User实体,它有一个list of Users(朋友)作为关系。

@Entity
public class User {

    @Id
    private String email;
    @Load
    private List<Ref<User>> friends = new ArrayList<Ref<User>>();

    private User() {
    }

    public List<User> getFriends() {
        ArrayList<User> friendList = new ArrayList<User>();
        for (Ref<User> ref : this.friends) {
            friendList.add(ref.get());
        }
        return friendList;
    }

    public void setFriends(List<User> friends) {
        List<Ref<User>> refs = new ArrayList<Ref<User>>();
        for (User user : friends) {
            refs.add(Ref.create(user));
        }
        this.friends = refs;
    }

}

现在,当我将以下用户存储在数据库中时,例如:user1user2

user1在他的朋友列表中有user2,反之亦然

当尝试从我的 Endpoint 获取 User 对象(具有上述循环引用)时,Android 客户端会引发以下异常:

com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[0]...

在这篇文章Infinite Recursion with Jackson JSON 和 Hibernate JPA 问题中,他们建议@JsonIgnore在字段或 getter/setter 方法上使用。但是在客户端,我需要通过这些 getter/setter 方法(从生成的客户端库对象)访问朋友列表,所以这对我没有帮助。

另一个技巧是使用@JsonManagedReference 和 @JsonBackReferenceManagedReference,在我的情况下不能应用,因为它们BackReference会指向同一个friends字段。

我认为可以解决我的问题的是@JsonIdentityInfo注释,它自Jackson 2.0.

我现在的问题是我不知道如何将此注释与 Google App Engine 一起使用。GAE 使用jackson-core-asl-1.9.11,不幸的是没有@JsonIdentityInfo,因为它显然取决于低于 2.0 的版本。

有谁知道,我如何在 Google App Engine 中使用最新的 Jackson 版本(2.4)来使用 @JsonIdentityInfo 功能?

还是有更好的方法来解决我的问题?

4

1 回答 1

0

最好的方法是定义一个 DTO 类作为端点的返回参数,并使用它来扁平化 JSON 响应(意味着不发送朋友的朋友的无限循环)。

于 2015-03-24T17:16:08.317 回答