【问题标题】:Objectify with Cloud Endpoints使用 Cloud Endpoints 进行对象化
【发布时间】:2013-11-11 12:12:19
【问题描述】:

我正在使用 appengine 云端点并进行对象化。我之前已经部署了这些端点,现在我正在更新它们,但它不适用于 Objectify。我已经搬到一台新机器上并运行最新的 appengine 1.8.6。尝试将 objectify 放在类路径中,但没有奏效。我知道这可以工作,我错过了什么??

运行endpoints.sh时:

Error: Parameterized type
   com.googlecode.objectify.Key<MyClass> not supported.

更新: 我回到我的旧计算机并在同一端点上运行 endpoints.sh,它运行良好。老机器有1.8.3。我正在使用objectify 3.1。

更新 2: 将我的旧机器更新到 1.8.6 并得到与其他机器相同的错误。留下2种可能性: 1)端点不再支持objectify 3.1 2) 端点在最新版本中存在错误

最有可能 #1...无论如何我一直想更新到 4.0...

【问题讨论】:

    标签: google-app-engine google-cloud-endpoints objectify


    【解决方案1】:

    由于 Objectify 的流行,在以前的版本中添加了一种解决方法来支持 Key 类型,直到有更通用的解决方案可用。由于新的解决方案可用,解决方法已被删除。您现在可以通过两种方式解决该属性的问题。

    1. 添加一个@ApiResourceProperty 注释,它会导致在序列化期间从对象中省略该键。如果您想要一个简单的解决方案并且不需要访问客户端中的密钥,请使用此方法。
    2. 添加一个@ApiTransformer 注释,它提供了一种兼容的机制来序列化/反序列化该字段。如果需要访问客户端中的密钥(或其表示),请使用此方法。由于这需要编写一个转换器类,因此它比第一个选项需要更多的工作。

    【讨论】:

    • 嗨,Dan,无关,我偶然发现了这个关于 Google Cloud Endpoints 限制的问题,我想知道它们是否仍然存在,答案会很好stackoverflow.com/questions/19786339/…
    • @Sti 您的意思是为 Objectify Keys 重新添加显式处理程序吗?我不这么认为。通用解决方案解决了 Objectify 案例和任何其他案例。
    • 好吧,我们需要在我们的 iOS 端点中访问对象的 ID。您的第一个解决方案完全忽略了该字段。据我们所见,第二种解决方案转换了整个对象,而不仅仅是您所说的“字段”。有没有办法只转换Key 属性以便端点可以访问它?
    • 您能谈谈这两种解决方案的优缺点吗?
    • @clocksmith 我已经添加了几句话。 PTAL
    【解决方案2】:

    我为我的项目想出了以下解决方案:

    @Entity
    public class Car {
    
        @Id Long id;
    
        @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
        Key<Driver> driver;
    
        public Key<Driver> getDriver() {
            return driver;
        }
    
        public void setDriver(Key<Driver> driver) {
            this.driver = driver;
        }
    
        public Long getDriverId() {
            return driver == null ? null : driver.getId();
        }
    
        public void setDriverId(Long driverId) {
            driver = Key.create(Driver.class, driverId);
        }
    }
    
    @Entity
    public class Driver {
        @Id Long id;
    }
    

    我知道,它有点样板,但是嘿 - 它可以工作并添加一些方便的快捷方法。

    【讨论】:

    • 您可以将@ApiResourceProperty 移动到该字段以节省一些混乱
    【解决方案3】:

    起初,我不明白 Flori 给出的答案,以及它到底有多大用处。因为其他人可能会受益,所以我将做一个简短的解释。

    如前所述,您可以使用@ApiTransformer 为您的类定义一个转换器。这会将不可序列化的字段(例如 Key&lt;myClass&gt; 类型的字段)转换为其他字段,例如 Long

    事实证明,当 GCE 处理一个类时,会自动使用名为 get{fieldName}set{FieldName} 的方法来转换字段 {fieldName}。我无法在 Google 文档的任何地方找到它。

    这是我在Exercise 类中将它用于Key{Machine} 属性的方法:

    public class Exercise {
      @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
      public Key<Machine> machine;
      // ... more properties
    
      public Long getMachineId() {
        return this.machine.getId();
      }
    
      public void setMachineId(Long machineId) {
        this.machine = new Key<Machine>(Machine.class, machineId);
      }
    
      // ...
    }
    

    【讨论】:

      【解决方案4】:

      其他人已经提到如何使用@ApiResourceProperty@ApiTransformer 来解决这个问题。但我确实需要客户端可用的密钥,我不想为每个人转换整个实体。我尝试将 Objectify Key 替换为 com.google.appengine.api.datastore.Key,看起来它在我的情况下也可以正常工作,因为这里的问题主要是由于该端点不支持参数化类型。

      【讨论】:

        猜你喜欢
        • 2018-12-28
        • 1970-01-01
        • 1970-01-01
        • 2018-12-29
        • 1970-01-01
        • 2019-11-06
        • 2013-12-21
        • 1970-01-01
        • 2014-10-03
        相关资源
        最近更新 更多