什么时候应该使用 RequestFactory 和 GWT-RPC?

发布于 2024-10-01 01:30:42 字数 231 浏览 8 评论 0原文

我试图弄清楚是否应该将 gwt-rpc 调用迁移到新的 GWT2.1 RequestFactory cal。

Google 文档含糊地提到 RequestFactory 是“面向数据的服务”的更好的客户端-服务器通信方法。

我可以从文档中提炼出的是,有一个新的 Proxy 类可以简化通信(您不必来回传递实际的实体,但只是代理,所以它的重量更轻,更容易管理)

这是重点还是我在大局中遗漏了其他东西?

I am trying to figure out if I should migrate my gwt-rpc calls to the new GWT2.1 RequestFactory cals.

Google documentation vaguely mentions that RequestFactory is a better client-server communication method for "data-oriented services"

What I can distill from the documentation is that there is a new Proxy class that simplifies the communication (you don't pass back and forth the actual entity but just the proxy, so it is lighter weight and easier to manage)

Is that the whole point or am I missing something else in the big picture?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

青朷 2024-10-08 01:30:42

GWT RPC 和RequestFactory 之间的最大区别在于,RPC 系统是“RPC-by-concrete-type”,而RequestFactory 是“RPC-by-interface”。

RPC 上手更方便,因为您编写的代码行更少,并且在客户端和服务器上使用相同的类。您可以创建一个包含大量 getter 和 setter 的 Person 类,也许还有一些简单的业务逻辑,用于进一步对 Person 对象中的数据进行切片和切块。这非常有效,直到您最终希望在类中包含特定于服务器的、非 GWT 兼容的代码。由于 RPC 系统基于客户端和服务器上具有相同的具体类型,因此您可能会遇到基于 GWT 客户端功能的复杂性障碍。

为了避免使用不兼容的代码,许多用户最终创建了一个对等 PersonDTO 来隐藏服务器上使用的真实 Person 对象。 PersonDTO 仅具有服务器端“域”Person 对象的 getter 和 setter 的子集。现在,您必须编写代码来编组 PersonPersonDTO 对象以及要传递给客户端的所有其他对象类型之间的数据。

RequestFactory 首先假设您的域对象不会与 GWT 兼容。您只需在 Proxy 接口中声明客户端代码应读取和写入的属性,RequestFactory 服务器组件将负责整理数据并调用您的服务方法。对于具有明确定义的“实体”或“具有身份和版本的对象”概念的应用程序,EntityProxy 类型用于向客户端代码公开数据的持久身份语义。简单对象使用 ValueProxy 类型进行映射。

使用 RequestFactory,您需要支付预先启动成本来适应比 GWT RPC 轻松支持的更复杂的系统。 RequestFactory 的 ServiceLayer 通过添加 ServiceLayerDecorator 实例。

The big difference between GWT RPC and RequestFactory is that the RPC system is "RPC-by-concrete-type" while RequestFactory is "RPC-by-interface".

RPC is more convenient to get started with, because you write fewer lines of code and use the same class on both the client and the server. You might create a Person class with a bunch of getters and setters and maybe some simple business logic for further slicing-and-dicing of the data in the Person object. This works quite well until you wind up wanting to have server-specific, non-GWT-compatible, code inside your class. Because the RPC system is based on having the same concrete type on both the client and the server, you can hit a complexity wall based on the capabilities of your GWT client.

To get around the use of incompatible code, many users wind up creating a peer PersonDTO that shadows the real Person object used on the server. The PersonDTO just has a subset of the getters and setters of the server-side, "domain", Person object. Now you have to write code that marshalls data between the Person and PersonDTO object and all other object types that you want to pass to the client.

RequestFactory starts off by assuming that your domain objects aren't going to be GWT-compatible. You simply declare the properties that should be read and written by the client code in a Proxy interface, and the RequestFactory server components take care of marshaling the data and invoking your service methods. For applications that have a well-defined concept of "Entities" or "Objects with identity and version", the EntityProxy type is used to expose the persistent identity semantics of your data to the client code. Simple objects are mapped using the ValueProxy type.

With RequestFactory, you pay an up-front startup cost to accommodate more complicated systems than GWT RPC easily supports. RequestFactory's ServiceLayer provides significantly more hooks to customize its behavior by adding ServiceLayerDecorator instances.

分开我的手 2024-10-08 01:30:42

我经历了从 RPC 到 RF 的转变。首先我不得不说我的经验是有限的,我使用了0个EntityProxies。

GWT RPC的优点:

  • 它非常容易设置、理解和学习!
  • 客户端和服务器上使用相同的基于类的对象。
  • 这种方法可以节省大量代码。
  • 理想情况下,当客户端和服务器上使用相同的模型对象(和 POJOS)时,POJO == MODEL OBJECT == DTO
  • 轻松将内容从服务器移动到客户端。
  • 易于在客户端和服务器之间共享通用逻辑的实现(当您需要不同的逻辑时,这可能会成为一个严重的缺点)。

GWT RPC 的缺点:

  • 不可能对服务器和客户端的某些方法有不同的实现,例如,您可能需要在客户端和服务器上使用不同的日志框架,或者不同的 equals 方法。
  • 非常糟糕的实现,无法进一步扩展:大多数服务器功能都是作为 RPC 类上的静态方法实现的。这真的很糟糕。
  • 例如,不可能添加服务器端错误混淆
  • 一些安全XSS问题无法很好地解决,请参阅文档(我不确定这对于RequestFactory是否更优雅)

RequestFactory的缺点:

  • 从官方文档中很难理解,它有什么好处!它从完全误导性的术语 PROXIES 开始——这些实际上是由 RF 自动创建的 RF DTO。代理由接口定义,例如@ProxyFor(Journal.class)。 IDE检查Journal上是否存在相应的方法。映射就这么多。
  • 就客户端和服务器的共性而言,RF 不会为您做太多事情,因为
  • 在客户端上,您需要将“PROXIES”转换为客户端域对象,反之亦然。这完全是荒谬的。它可以通过声明性的几行代码来完成,但没有对此的支持!如果我们能够更优雅地将域对象映射到代理,RF 工具箱中就缺少 JavaScript 方法 JSON.stringify(..,,) 之类的东西。
  • 不要忘记您还负责将域对象的可转移属性设置为代理,等等。
  • 服务器上的错误处理很差 - 默认情况下,服务器上会省略堆栈跟踪,并且您在客户端上会收到空的无用异常。即使我设置了自定义错误处理程序,我也无法访问低级堆栈跟踪!糟糕的。
  • IDE 支持和其他地方的一些小错误。我提交了两个已被接受的错误请求。不需要爱因斯坦就能弄清楚这些实际上是错误。
  • 文档很糟糕。正如我提到的,代理应该得到更好的解释,这个术语是有误导性的。对于我正在解决的基本常见问题,文档是没有用的。 DOC 误解的另一个例子是将 JPA 注释与 RF 联系起来。从简洁的文档来看,它们有点一起玩,是的,StackOverflow 上有一个相应的问题。我建议在理解 RF 之前忘记任何 JPA“连接”。

RequestFactory 的优点

  • 优秀的论坛支持。
  • IDE 支持非常好(但与 RPC 相比不是优势)
  • 客户端和服务器实现的灵活性(松散耦合)
  • 花哨的东西,连接到 EntityProxies,超越简单的 DTO - 缓存,部分更新,对于移动非常有用。
  • 您可以使用 ValueProxies 作为 DTO 最简单的替代品(但您必须自己完成所有不那么花哨的转换)。
  • 支持 Bean 验证 JSR-303。

考虑到 GWT 的其他缺点:

  • 无法使用提供的 JUnit 支持来运行集成测试(GWT 客户端代码 + 远程服务器)<= 所有 JSNI 都必须被模拟(例如 localStorage),SOP 是一个问题。

  • 不支持测试设置 - 无头浏览器 + 远程服务器 <= 没有针对 GWT、SOP 的简单无头测试。

    不支持

  • 是的,可以运行selenium集成测试(但这不是我想要的)

  • JSNI非常强大,但是在他们在会议上发表的那些精彩演讲中,他们并没有过多谈论编写 JSNI 代码也有一些规则。同样,弄清楚如何编写一个简单的回调是真正的研究人员值得完成的任务。

综上所述,从 GWT RPC 过渡到 RequestFactory 远不是 WIN-WIN 的情况,
当 RPC 最能满足您的需求时。您最终会编写大量从客户端域对象到代理的转换,反之亦然。但您的解决方案具有一定的灵活性和稳健性。论坛的支持非常好,周六也是如此!

考虑到我刚才提到的所有优点和缺点,提前考虑这些方法是否能够真正改善您的解决方案和开发设置,而不需要进行重大权衡,这是非常值得的。

I went through a transition from RPC to RF. First I have to say my experience is limited in that, I used as many EntityProxies as 0.

Advantages of GWT RPC:

  • It's very easy to set-up, understand and to LEARN!
  • Same class-based objects are used on the client and on the server.
  • This approach saves tons of code.
  • Ideal, when the same model objects (and POJOS) are used on either client and server, POJOs == MODEL OBJECTs == DTOs
  • Easy to move stuff from the server to client.
  • Easy to share implementation of common logic between client and server (this can turn out as a critical disadvantage when you need a different logic).

Disadvatages of GWT RPC:

  • Impossible to have different implementation of some methods for server and client, e.g. you might need to use different logging framework on client and server, or different equals method.
  • REALLY BAD implementation that is not further extensible: most of the server functionality is implemented as static methods on a RPC class. THAT REALLY SUCKS.
  • e.g. It is impossible to add server-side errors obfuscation
  • Some security XSS concerns that are not quite elegantly solvable, see docs (I am not sure whether this is more elegant for RequestFactory)

Disadvantages of RequestFactory:

  • REALLY HARD to understand from the official doc, what's the merit of it! It starts right at completely misleading term PROXIES - these are actually DTOs of RF that are created by RF automatically. Proxies are defined by interfaces, e.g. @ProxyFor(Journal.class). IDE checks if there exists corresponding methods on Journal. So much for the mapping.
  • RF will not do much for you in terms of commonalities of client and server because
  • On the client you need to convert "PROXIES" to your client domain objects and vice-versa. This is completely ridiculous. It could be done in few lines of code declaratively, but there's NO SUPPORT FOR THAT! If only we could map our domain objects to proxies more elegantly, something like JavaScript method JSON.stringify(..,,) is MISSING in RF toolbox.
  • Don't forget you are also responsible for setting transferable properties of your domain objects to proxies, and so on recursively.
  • POOR ERROR HANDLING on the server and - Stack-traces are omitted by default on the server and you re getting empty useless exceptions on the client. Even when I set custom error handler, I was not able to get to low-level stack traces! Terrible.
  • Some minor bugs in IDE support and elsewhere. I filed two bug requests that were accepted. Not an Einstein was needed to figure out that those were actually bugs.
  • DOCUMENTATION SUCKS. As I mentioned proxies should be better explained, the term is MISLEADING. For the basic common problems, that I was solving, DOCS IS USELESS. Another example of misunderstanding from the DOC is connection of JPA annotations to RF. It looks from the succinct docs that they kinda play together, and yes, there is a corresponding question on StackOverflow. I recommend to forget any JPA 'connection' before understanding RF.

Advantages of RequestFactory

  • Excellent forum support.
  • IDE support is pretty good (but is not an advantage in contrast with RPC)
  • Flexibility of your client and server implementation (loose coupling)
  • Fancy stuff, connected to EntityProxies, beyond simple DTOs - caching, partial updates, very useful for mobile.
  • You can use ValueProxies as the simplest replacement for DTOs (but you have to do all not so fancy conversions yourself).
  • Support for Bean Validations JSR-303.

Considering other disadvantages of GWT in general:

  • Impossible to run integration tests (GWT client code + remote server) with provided JUnit support <= all JSNI has to be mocked (e.g. localStorage), SOP is an issue.

  • No support for testing setup - headless browser + remote server <= no simple headless testing for GWT, SOP.

  • Yes, it is possible to run selenium integration tests (but that's not what I want)

  • JSNI is very powerful, but at those shiny talks they give at conferences they do not talk much about that writing JSNI codes has some also some rules. Again, figuring out how to write a simple callback was a task worth of true researcher.

In summary, transition from GWT RPC to RequestFactory is far from WIN-WIN situation,
when RPC mostly fits your needs. You end up writing tons conversions from client domain objects to proxies and vice-versa. But you get some flexibility and robustness of your solution. And support on the forum is excellent, on Saturday as well!

Considering all advantages and disadvantages I just mentioned, it pays really well to think in advance whether any of these approaches actually brings improvement to your solution and to your development set-up without big trade-offs.

诗笺 2024-10-08 01:30:42

我发现为所有实体创建代理类的想法非常烦人。我的 Hibernate/JPA pojo 是从数据库模型自动生成的。为什么我现在需要为 RPC 创建第二个镜像?我们有一个很好的“estivation”框架,负责“解除休眠”pojo。

另外,定义服务接口的想法并不完全将服务器端服务实现为 java 契约,但确实实现了方法 - 对我来说听起来非常 J2EE 1.x/2.x。

I find the idea of creating Proxy classes for all my entities quite annoying. My Hibernate/JPA pojos are auto-generated from the database model. Why do I now need to create a second mirror of those for RPC? We have a nice "estivation" framework that takes care of "de-hibernating" the pojos.

Also, the idea of defining service interfaces that don't quite implement the server side service as a java contract but do implement the methods - sounds very J2EE 1.x/2.x to me.

转瞬即逝 2024-10-08 01:30:42

与错误处理和测试能力较差的 RequestFactory 不同(因为它在 GWT 的引擎盖下处理大部分内容),RPC 允许您使用更加面向服务的方法。 RequestFactory 实现了一种更现代的依赖注入风格的方法,如果您需要调用复杂的多态数据结构,它可以提供有用的方法。使用 RPC 时,您的数据结构需要更加扁平,因为这将允许您的编组实用程序在 json/xml 和 java 模型之间进行转换。使用 RPC 还允许您实现更健壮的架构,如 Google 网站上的 gwt dev 部分所引用。

“简单的客户端/服务器部署

考虑服务定义的第一个也是最直接的方法是将它们视为应用程序的整个后端。从这个角度来看,客户端代码是您的“前端”,所有服务代码都运行在服务器是“后端”。如果采用这种方法,您的服务实现将趋向于更通用的 API,不会与特定应用程序紧密耦合。您的服务定义可能会通过 JDBC 或 Hibernate 甚至文件直接访问数据库。对于许多应用程序来说,这种视图是合适的,并且非常高效,因为它减少了多层

部署

。在更复杂的多层体系结构中,您的 GWT 服务定义可以是轻量级的。调用后端服务器环境(例如 J2EE 服务器)的网关 从这个角度来看,您的服务可以被视为应用程序用户界面的“服务器一半”。服务不是通用的,而是为用户界面的特定需求而创建的。您的服务成为“后端”类的“前端”,这些类是通过将对更通用的后端服务层的调用缝合在一起而编写的,例如,作为 J2EE 服务器集群实现。如果您需要后端服务在与 HTTP 服务器物理上分离的计算机上运行,​​这种架构是合适的。”

另请注意,设置单个 RequestFactory 服务需要创建大约 6 个左右的 java 类,而 RPC 仅需要 3 个类在我的书中,更多的代码==更多的错误和复杂性。RequestFactory

在请求处理过程中也有更多的开销,因为它必须在数据代理和实际的 java 模型之间编组序列化,这会增加额外的处理周期。在企业或生产环境中,

我也不相信 RequestFactory 服务是像 RPC 服务一样的序列化。

总而言之,在使用这两种服务一段时间后,我总是选择 RPC,因为它更轻量级,更易于测试和调试。 ,并且比使用 RequestFactory 更快。尽管 RequestFactory 可能比它的 RPC 对应部分更优雅和可扩展,但增加的复杂性并不意味着它是一个更好的工具。

我的观点是,最好的架构是使用两个 Web 应用程序,一个客户端和一个服务器。该服务器是一个简单的轻量级通用 java web 应用程序,使用 servlet.jar 库。客户端是GWT。您通过 GWT-RPC 向客户端 Web 应用程序的服务器端发出 RESTful 请求。客户端的服务器端只是到 apache http 客户端的一个传递,它使用持久隧道进入您在服务器 servlet Web 应用程序中作为单个 servlet 运行的请求处理程序。 Servlet Web 应用程序应该包含您的数据库应用程序层(hibernate、cayenne、sql 等)。这允许您将数据库对象模型与实际客户端完全分离,从而提供一种更具可扩展性和健壮性的方式来开发和单元测试您的应用程序。当然,它需要一点初始设置时间,但最终允许您在 GWT 之外创建一个动态请求工厂。这使您能够充分利用两全其美的优势。更不用说能够测试和更改服务器端而无需编译或构建 gwt 客户端。

Unlike RequestFactory which has poor error handling and testing capabilities (since it processes most of the stuff under the hood of GWT), RPC allows you to use a more service oriented approach. RequestFactory implements a more modern dependency injection styled approach that can provide a useful approach if you need to invoke complex polymorphic data structures. When using RPC your data structures will need to be more flat, as this will allow your marshaling utilities to translate between your json/xml and java models. Using RPC also allows you to implement more robust architecture, as quoted from the gwt dev section on Google's website.

"Simple Client/Server Deployment

The first and most straightforward way to think of service definitions is to treat them as your application's entire back end. From this perspective, client-side code is your "front end" and all service code that runs on the server is "back end." If you take this approach, your service implementations would tend to be more general-purpose APIs that are not tightly coupled to one specific application. Your service definitions would likely directly access databases through JDBC or Hibernate or even files in the server's file system. For many applications, this view is appropriate, and it can be very efficient because it reduces the number of tiers.

Multi-Tier Deployment

In more complex, multi-tiered architectures, your GWT service definitions could simply be lightweight gateways that call through to back-end server environments such as J2EE servers. From this perspective, your services can be viewed as the "server half" of your application's user interface. Instead of being general-purpose, services are created for the specific needs of your user interface. Your services become the "front end" to the "back end" classes that are written by stitching together calls to a more general-purpose back-end layer of services, implemented, for example, as a cluster of J2EE servers. This kind of architecture is appropriate if you require your back-end services to run on a physically separate computer from your HTTP server."

Also note that setting up a single RequestFactory service requires creating around 6 or so java classes where as RPC only requires 3. More code == more errors and complexity in my book.

RequestFactory also has a little bit more overhead during the request processing, as it has to marshal serialization between the data proxies and actual java models. This added interface adds extra processing cycles which can really add up in an enterprise or production environment.

I also do not believe that RequestFactory services are serialization like RPC services.

All in all after using both for some time now, i always go with RPC as its more lightweight, easier to test and debug, and faster then using a RequestFactory. Although RequestFactory might be more elegant and extensible then its RPC counter part. The added complexity does not make it a better tool necessary.

My opinion is that the best architecture is to use two web apps , one client and one server. The server is a simple lightweight generic java webapp that uses the servlet.jar library. The client is GWT. You make RESTful request via GWT-RPC into the server side of the client web application. The server side of the client is just a pass though to apache http client which uses a persistant tunnel into the request handler you have running as a single servlet in your server servlet web application. The servlet web application should contain your database application layer (hibernate, cayenne, sql etc..) This allows you to fully divorce the database object models from the actual client providing a much more extensible and robust way to develop and unit test your application. Granted it requires a tad bit of initial setup time, but in the end allows you to create a dynamic request factory sitting outside of GWT. This allows you to leverage the best of both worlds. Not to mention being able to test and make changes to your server side without having to have the gwt client compiled or build.

花落人断肠 2024-10-08 01:30:42

我认为如果您在客户端有大量的 pojo,例如如果您使用 Hibernate 或 JPA 实体,那么这确实很有帮助。
我们采用了另一种解决方案,使用 Django 风格的持久性框架和非常轻的实体。

I think it's really helpful if you have a heavy pojo on the client side, for example if you use Hibernate or JPA entities.
We adopted another solution, using a Django style persistence framework with very light entities.

谁的年少不轻狂 2024-10-08 01:30:42

我要提出的唯一警告是 RequestFactory 使用二进制数据传输(也许是 deRPC?)而不是普通的 GWT-RPC。

仅当您使用 SyncProxy、Jmeter、Fiddler 或任何可以读取/评估 HTTP 请求/响应内容的类似工具(如 GWT-RPC)进行大量测试时,这一点才重要,但使用 deRPC 或 RequestFactory 会更具挑战性。

The only caveat I would put in is that RequestFactory uses the binary data transport (deRPC maybe?) and not the normal GWT-RPC.

This only matters if you are doing heavy testing with SyncProxy, Jmeter, Fiddler, or any similar tool that can read/evaluate the contents of the HTTP request/response (like GWT-RPC), but would be more challenging with deRPC or RequestFactory.

海拔太高太耀眼 2024-10-08 01:30:42

我们的项目中有一个非常大的 GWT-RPC 实现。
实际上,我们有 50 个 Service 接口,每个接口都有很多方法,并且编译器生成的 TypeSerializer 的大小会导致我们的 JS 代码变得巨大,因此我们遇到了问题。
所以我们正在分析转向RequestFactory。
我已经阅读了几天的内容,深入网络并试图找到其他人在做什么。
我看到的最重要的缺点(也许我可能是错的)是,使用 RequestFactory,您将不再控制服务器域对象和客户端对象之间的通信。
我们需要的是以受控的方式应用加载/保存模式。我的意思是,例如客户端接收属于特定事务的对象的整个对象图,进行更新并将整个对象发送回服务器。服务器将负责进行验证、将旧值与新值进行比较并进行持久化。如果来自不同站点的 2 个用户获得相同的交易并进行一些更新,则生成的交易不应该是合并的交易。在我的场景中,其中一项更新应该会失败。
我没有看到 RequestFactory 有助于支持这种处理。

问候
丹尼尔

We have have a very large implementation of GWT-RPC in our project.
Actually we have 50 Service interfaces with many methods each, and we have problems with the size of TypeSerializers generated by the compiler that turns our JS code huge.
So we are analizing to move towards RequestFactory.
I have been read for a couple of days digging into the web and trying to find what other people are doing.
The most important drawback I saw, and maybe I could be wrong, is that with RequestFactory your are no longer in control of the communication between your Server Domain objects and your client ones.
What we need is apply the load / save pattern in a controlled way. I mean, for example client receive the whole object graph of objects belonging to a specific transaction, do his updates and them send the whole back to the server. The server will be responsible for doing validation, compare old with new values and do persistance. If 2 users from different sites gets the same transaction and do some updates, the resulting transaction shouldn't be the merged one. One of the updates should fail in my scenario.
I don't see that RequestFactory helps supporting this kind of processing.

Regards
Daniel

極樂鬼 2024-10-08 01:30:42

公平地说,当考虑有限的 MIS 应用程序时,比如有 10-20 个可 CRUD 的业务对象,每个对象都有大约 1-10 个属性,这真的取决于个人偏好选择哪条路线?

如果是这样,那么预测您的应用程序将如何扩展可能是选择路线 GWT RPC 或 RequestFactory 的关键:

  1. 我的应用程序预计将保留相对有限数量的实体,但在实体数量方面将大幅增加数字。 10-20 个对象 * 100,000 条记录。

  2. 我的应用程序的实体范围将显着增加,但每个实体涉及的相对数量仍将保持较低。 5000 个对象 * 100 条记录。

  3. 我的应用程序预计将保留相对有限数量的实体,并且将保留相对较少的数量,例如 10-20 个对象 * 100 条记录

在我的例子中,我正处于尝试做出此决定的起点。由于必须更改 UI 客户端架构以及做出传输选择,情况变得更加复杂。我之前的(相当大的)大规模 GWT UI 使用了 Hmvc4Gwt 库,该库已被 GWT MVP 工具取代。

Is it fair to say that when considering a limited MIS application, say with 10-20 CRUD'able business objects, and each with ~1-10 properties, that really it's down to personal preference which route to go with?

If so, then perhaps projecting how your application is going to scale could be the key in choosing your route GWT RPC or RequestFactory:

  1. My application is expected to stay with that relatively limited number of entities but will massively increase in terms of their numbers. 10-20 objects * 100,000 records.

  2. My application is going to increase significantly in the breadth of entities but the relative numbers involved of each will remain low. 5000 objects * 100 records.

  3. My application is expected to stay with that relatively limited number of entities AND will stay in relatively low numbers of e.g. 10-20 objects * 100 records

In my case, I'm at the very starting point of trying to make this decision. Further complicated by having to change UI client side architecture as well as making the transport choice. My previous (significantly) large scale GWT UI used the Hmvc4Gwt library, which has been superseded by the GWT MVP facilities.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文