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


87

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

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

我从文档中可以得出的是,有一个新的Proxy类简化了通信(您不来回传递实际实体,而只是来回传递代理,因此它的重量更轻且易于管理)

这是整个观点还是我在全局中遗漏了其他东西?


8
是的,这个问题与官方的gwt devguide链接!
törzsmókus

Answers:


73

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

RPC入门起来比较方便,因为您只需编写更少的代码行,并且在客户端和服务器上都使用相同的类。您可能会创建一个Person带有一堆getter和setter的类,并可能使用一些简单的业务逻辑来进一步对Person对象中的数据进行切片和切块。直到您最终希望在类中包含特定于服务器的,非GWT兼容的代码之前,这非常有效。由于RPC系统基于客户端和服务器上具有相同的具体类型,因此您可以根据GWT客户端的功能来创建复杂性墙。

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

通过假设您的域对象将不兼容GWT来启动RequestFactory。您只需在Proxy接口中声明客户端代码应读取和写入的属性,RequestFactory服务器组件即可处理数据封送和调用服务方法。对于具有“实体”或“具有标识和版本的对象”的明确定义的应用程序,该EntityProxy类型用于将数据的持久标识语义公开给客户端代码。简单对象使用ValueProxy类型进行映射。

使用RequestFactory,您需要支付前期启动成本,以适应GWT RPC轻松支持的更复杂的系统。ServiceLayer通过添加ServiceLayerDecorator实例,RequestFactory提供了更多的挂钩来自定义其行为。


这是支持我决定切换到RequestFactory的一个很好的理由。谢谢你,鲍勃!这是有道理的,我不明白为什么有人说“根据需要,在某些情况下使用RPC,在其他情况下使用RF”,因为好像使用RPC一样,您必须编写大量粘合代码和DTO层
DanL。

5
RequestFactory的另一个优点是可以与Android和GWT使用完全相同的代码。
Patrick

28

我经历了从RPC到RF的过渡。首先,我不得不说,我的经验有限,因为我使用了最多0个EntityProxies。

GWT RPC的优点:

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

GWT RPC的缺点:

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

RequestFactory的缺点:

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

RequestFactory的优点

  • 出色的论坛支持。
  • IDE支持非常好(但与RPC相比不是优势)
  • 客户端和服务器实现的灵活性(松耦合)
  • 除了简单的DTO之外,连接到EntityProxies的精美东西-缓存,部分更新,对于移动设备非常有用。
  • 您可以将ValueProxies用作DTO的最简单替代品(但您必须自己做一些不太花哨的转换)。
  • 支持Bean验证JSR-303。

通常考虑GWT的其他缺点:

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

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

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

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

总而言之,当RPC最适合您的需求时,从GWT RPC过渡到RequestFactory并非双赢。您最终要编写从客户端域对象到代理的吨转换,反之亦然。但是您将获得解决方案的灵活性和鲁棒性。论坛上的支持非常出色,星期六也是如此!

考虑到我刚才提到的所有优点和缺点,事先考虑一下这些方法是否真正在不带来重大折衷的情况下真正为您的解决方案和开发设置带来了改善是非常必要的。


结帐JBoss Erai。我喜欢他们的RPC方法。
Καrτhικ

6

我发现为所有实体创建代理类的想法很烦人。我的Hibernate / JPA pojos是从数据库模型自动生成的。为什么现在需要为RPC创建第二个镜像?我们有一个不错的“诱人”框架,可以“消除” pojos的休眠。

另外,定义服务接口的想法并不能完全将服务器端服务实现为Java合约,但可以实现方法-对我来说听起来很像J2EE 1.x / 2.x。


5
这很烦人,但是如果您仍然必须创建代理,那么您将希望获得RF提供的额外帮助来管理这些代理。并非每个人都希望将整个pojo发送给客户端-例如,考虑一个扑克游戏-您的Player对象可能具有每个人都应该看到的信息(手牌数量,面朝上的牌,总筹码)以及仅一个玩家应该看到(正面朝下的纸牌)。
Peter Recore 2011年

您的扑克示例是有效的-我们通过添加注释(@WireTransient)来解决该问题,我们的“动机”框架使用该注释来抑制值。
Καrτhικ

4

与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,因为RPC更轻巧,更易于测试和调试,并且比使用RequestFactory更快。尽管RequestFactory可能更优雅和可扩展,但其RPC计数器部分。增加的复杂性并不能使其成为更好的工具。

我认为最好的架构是使用两个Web应用程序,一个客户端和一个服务器。该服务器是使用servlet.jar库的简单轻量级通用Java Web应用程序。客户端是GWT。您通过GWT-RPC向客户端Web应用程序的服务器端发出RESTful请求。客户端的服务器端只是对Apache客户端的传递,它使用持久性隧道进入您在服务器Servlet Web应用程序中作为单个Servlet运行的请求处理程序。Servlet Web应用程序应包含您的数据库应用程序层(休眠,Cayenne,SQL等)。这允许您将数据库对象模型与实际客户端完全分开,从而提供了一种更可扩展且更可靠的方法来开发和进行应用程序测试。当然,这需要一点点的初始设置时间,但最后,您可以在GWT外部创建一个动态请求工厂。这使您可以利用两全其美的优势。更不用说无需编译或构建gwt客户端就可以测试和更改服务器端。


0

我认为,如果在客户端使用大量的pojo,例如使用Hibernate或JPA实体,这真的很有帮助。我们采用了另一种解决方案,即使用具有非常轻量实体的Django样式持久性框架。


0

我唯一需要说明的是,RequestFactory使用二进制数据传输(也许是deRPC吗?),而不是普通的GWT-RPC。

仅当您正在使用SyncProxy,Jmeter,Fiddler或任何其他可以读取/评估HTTP请求/响应的内容(例如GWT-RPC)的工具进行大量测试时,这才有意义,但是对于deRPC或RequestFactory则更具挑战性。


1
除了实际上RequestFactory确实提供了开箱即用的“纯Java”实现之外,不需要SyncProxy之类的第三方工具。见stackoverflow.com/questions/4853188/...
托马斯Broyer

0

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

问候丹尼尔


我也有同样的担忧...您最终选择了RF吗?
HDave

0

可以公平地说,当考虑使用有限的MIS应用程序时,例如具有10-20个CRUD'able业务对象,并且每个业务对象具有约1-10个属性,那么,这实际上取决于个人喜好,该选择哪种方法?

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

  1. 预计我的申请将保留在数量相对有限的实体中,但实体数量将大量增加。10-20个对象* 100,000条记录。

  2. 我的应用程序将在实体的广度上显着增加,但是每个实体所涉及的相对数量将保持较低水平。5000个对象* 100条记录

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

就我而言,我正处于尝试做出此决定的起点。由于必须更改UI客户端体系结构以及做出传输选择,因此进一步复杂化。我以前的(显着)大规模GWT UI使用了Hmvc4Gwt库,该库已被GWT MVP设施所取代。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.