关于GWT如何与Application层进行整合一些思考

08-02-22 boommen
大家好!最近在做GWT的项目,对GWT如何同Server端的服务进行整合有一些想法,希望能和大家讨论一下。
使用GWT的RPC与Server通信时,需要定义两个Service接口,分别代表同步和异步调用。在接口中可以直接定义业务逻辑相关的方法如login, logout,这是是最直接的方式,它的好处是:
1 Client端调用时非常简单,直接;
2 Client端的调用如何转换为Server端的调用由GWT负责;
它的缺点是:
1 随着Client端业务的增加,会不断的增加新的接口,或者在已有接口中增加新的方法;
2 每一个业务方法都需要在两个接口中定义;
3 每一个业务方法都需要在Server端实现;
4 Client对Server的每一个调用,都要由相应的Application层代码完成。由于Application层接受的参数和返回值可能是属于 Application层的类,如果GWT的代码和这些类产生耦合,GWT的编译器会将大量的Java代码转换成JavaScript代码,所以在 Client端的Service接口与Application层提供的接口虽然可能有一致的业务逻辑语义,但却不能有同样的签名。这意味着GWT需要定义一套类似Application层的接口,Server端的接口实现负责将GWT的调用转换成对Application层的调用,再将 Application层的返回结果转换为GWT能够接受的形式(DTO),这一过程会很繁琐。比如要实现login业务,需要做的事情包括:
1)在Client端定义LoginService接口及方法;
2)在Client端定义LoginServiceAsync接口及方法;
3)在Server端实现LoginService接口的方法;
4)在接口实现中将参数转换为Application层的数据(如果需要的话),调用Application层的方法,并将返回值转换成GWT可接受的形式。

另外一个想法是,Client端的Service接口中只定义一个方法:
GWTResponse handleRequest( GWTRequest request);
所有的业务请求都通过这个接口发送给Server端,Server端根据request中的参数决定如何使用Application层,以及如何将处理返回值。
这种做法的好处是
1 Client端的Serivce接口非常稳定,不需要维护;
2 Server端只需要实现一个接口的一个方法;
3 可以在架构设计上想一些办法,方便的实现GWT的请求映射为对Application层的请求,包括参数的转换和返回值的转换,而不需要程序员编码实现;
缺点是:
1 Client端的调用不如上一种方法直观;
2 有两种方法定义request和response,一种是对于每一种请求定义不同的类,如LoginRequest,LoginResponse,这种方法的好处是直观,有编译检查,缺点是增加类的数量;另一种方法是使用类似于Map的容器,好处是不需增加类的数量,缺点是没有编译检查,Client端和 Server端的一致性需要程序员来保证。对第二种方法可以进行增强,如定义常量类规定参数名称和返回值名称,但这样又要增加类的数量;

第二种想法实质上是模仿了Servlet架构的设计。在Servlet的api中,service方法负责接收浏览器的参数,并生成响应结果。在 Servlet中,所有的参数都是String,包括命令也是String,响应结果也是以String的形式发送给浏览器,这实际上是牺牲了Java作为一种强类型语言的特性(类型检查,方法调用),因为发起请求的浏览器使用的语言(Html)和协议(Http)并不是专为Java设计,是不得已而为之;而在GWT中,Client端已经将请求的形式转为Java语言,那为什么还要转化为类似Request的方式,而不是直接调用相应的方法(LoginService.login())呢?我认为主要是GWT这个框架的限制导致的,GWT实现了Client和Server在语言上的统一(Java),但却并不见得完全没有阻抗,比如GWT要求定义两个接口(同步和异步),在Server端必须对接口进行实现,为避免转换太多的Java代码而不能直接使用Application的接口定义等等,这些限制使得我们不能像使用Swing一样得心应手,为了符合规定而书写大量的代码。

2
banq
2008-02-22 20:28
既然GWT能够让我们以java来开发AJAX,这是其方便之处,必然也有不便地方,第一种方式的不便还是可以忍受的。

猜你喜欢