客观化列表<ref <t>&gt;未经Google App Engine端点序列化</ref <t>

时间:2014-02-04 14:50:31

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

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

这是实体的摘要视图:

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 <Ref<Car>> 类型,但我发现了这个有趣的解决方法:< / p>

我创建了班级 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 。它通过一次调用获取客户数据以及他拥有的所有汽车( makeAndModel plateNumber )。

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

  

java.io.IOException的:   com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException:   直接自我引用导致循环(通过参考链:   entity.Customer [ “汽车”] - &GT; java.util.ArrayList中[0] - &GT; com.googlecode.objectify.impl.ref.LiveRef [ “键”] - &GT; com.googlecode.objectify.Key [”根“])

在1.8.9中有效的任何其他解决方法吗? @ApiTransformer是唯一的选择吗?

1 个答案:

答案 0 :(得分:3)

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

我将List<Ref<Car>> 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());
}

这就是全部