【问题标题】:Objectify List<Ref<T>> not serialized by Google App Engine endpointsObjectify List<Ref<T>> 未由 Google App Engine 端点序列化
【发布时间】:2014-02-28 14:36:42
【问题描述】:

您好有两个相关的实体:客户和汽车。每个客户可以拥有几辆汽车

这是实体的汇总视图:

public class Customer 
{
    //Inner classes for partial loads
    public static class NoCars{}

    @Id protected String id;
    private String fullName;
    @Load(unless=NoCars.class) private List<Ref<Car>> cars;
}

public class Car
{
    @Id private Long id;
    private String makeAndModel;
    private String plateNumber;
}

这是一种从数据存储和他拥有的所有汽车中检索客户的方法:

public Customer getCustomer(@Named("id") String customerId)
{
    Customer customer =  ofy().load().type(Customer.class).id(customerId).now();
    if (customer==null)
        throw new NotFoundException("customer not found");
    else
        return customer;
}

endpoints.sh 无法实现这一点,因为返回类型 Customer 中包含的类型 List &lt;Ref&lt;Car&gt;&gt; 不受支持,但我发现了这个有趣的解决方法:

我创建了类CustomerPOJO

public class CustomerPOJO
{
    private String fullName;
}

并修改了类 Customer 以扩展它

public class Customer extends CustomerPOJO
{
    //Inner classes for partial loads
    public static class NoCars{}

    @Id protected String id;
    @Load(unless=NoCars.class) private List<Ref<Car>> cars = new ArrayList<>();
}

getter 方法是:

public CustomerPOJO getCustomer(@Named("id") String customerId)
{
    Customer customer =  ofy().load().type(Customer.class).id(customerId).now();
    if (customer==null)
        throw new NotFoundException("customer not found");
    else
        return customer;
}

请注意,该方法将 CustomerPOJO 声明为返回类型,但它实际上返回“完整”Customer!!!

这适用于 AppEngine 1.8.0 + Objectify 4.0 RC2。它在一次调用中获取客户数据和他拥有的所有汽车及其属性(makeAndModelplateNumber)。

升级到 1.8.9 后出现问题。 endpoints.sh 仍然有效,因为返回类型完全兼容,但是在运行时将 Customer objecto 解析为 JSON 时出现异常。

java.io.IOException: com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: 直接自引用导致循环(通过引用链: entity.Customer["cars"]->java.util.ArrayList[0]->com.googlecode.objectify.impl.ref.LiveRef["key"]->com.googlecode.objectify.Key["root"] )

还有其他适用于 1.8.9 的解决方法吗? @ApiTransformer 是唯一的选择吗?

【问题讨论】:

    标签: java json google-app-engine objectify endpoints


    【解决方案1】:

    解决方案非常简单...只需隐藏 Ref 字段。它现在确实为 API 使用者提供了任何价值,但它只会给解析器带来麻烦:

    我将List&lt;Ref&lt;Car&gt;&gt; getter 和 setter 替换为:

    public List<Car> getCars()
    {
        List<Car> ret = new ArrayList<>();
        Iterator<Ref<Car>> it = cars.iterator();
    
        while (it.hasNext())
            ret.add(it.next().getValue());
        return ret;
    }
    
    public void setCars(List<Car> newCars)
    {
        Iterator<Car> it = newCars.iterator();
    
        while (it.hasNext())
            addCar(it.next());
    }
    

    就是这样

    【讨论】:

      猜你喜欢
      • 2011-06-19
      • 2014-08-09
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      相关资源
      最近更新 更多