gpt4 book ai didi

java - 如何防止客户端更改 Google Cloud Endpoints 中的 objectify @ID

转载 作者:行者123 更新时间:2023-12-01 12:56:35 26 4
gpt4 key购买 nike

我正在使用 objectify 将对象保存到 Google Cloud 数据存储区。 “主键”用@Id注释。

@Entity
class Car {
@Id Long id;
...
}

我生成客户端端点(使用 Android Studio)。

我需要所有字段(包括 id)的 getter 和 setter,以便 REST 能够序列化和反序列化对象。如果我不添加 getter 和 setter,那么它们将由 Google 端点构建器创建。

通常,客户端从数据存储中获取实例,更改属性并将其更新回来。后端处理新属性并将它们存储在数据存储中。

只要 id 相同,就可以正常工作。但是当客户端更改 id 时会发生什么?因为服务器是无状态的,所以它认为另一个对象已被更新,并且插入或更新了错误的对象。换句话说,如果新的 id 已存在于数据存储中,则更新该记录;如果不存在,则创建具有该 id 的新记录。

这种行为是数据存储所固有的,但是如果客户端更改了 id,这会弄乱数据库,因此必须有一种方法来防止这种情况发生。

我可以看到两种解决方案:

  1. 按照此处的建议 GAE - Getter without Setter - How to prevent client from writing a given property? How to prevent client from modifying the object ID?通过@zgc7009,我可以将 setter 留空并让它不执行任何操作。我已经尝试过了,只要没有相关对象,它就可以工作。

  2. 我可以在后端使用版本字段,每次调用 UPDATE 时都会递增该版本字段。这允许我验证客户端版本是否==服务器版本 - 1,如果不是则抛出异常。此措施可以减少更新错误记录的机会,但需要在每次写入之前从数据存储中读取数据,因此效率不高。

由于这两种解决方案都不好,我相信 Google 的某个人一直在考虑这个问题,并且必须有更好的方法来确保 REST 中的数据完整性。根据我的理解 - 我不知道是否可以更改 - Google Endpoints API 的生成方式是 id 不包含在 URL 中,或者这种情况发生在幕后。换句话说:通常,存储对象的 ID 包含在 URL(元数据)中。在这里,它包含在对象(有效负载)中,因此可以由客户端更改。

有人可以透露一下吗?

PS:我知道上例中数据存储的最佳实践可能会使用 VIN 作为 ID,但这并不总是可行。有些对象无法创建用作 id 的唯一标识符。

最佳答案

这似乎是许多人都面临的常见问题。您可以做一件事:

上面的解决方案 2 是一个很好的解决方案,但您担心在每次写入之前从数据存储读取。这可以通过使用 @Cache 注解您的实体类来缓解,以便客户端第一次检索实体时它们将被缓存。这样,当客户端调用您的后端进行更新或执行任何操作时,您在比较版本时将不会访问数据存储

关于java - 如何防止客户端更改 Google Cloud Endpoints 中的 objectify @ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23835511/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com