`
javatar
  • 浏览: 1680328 次
  • 性别: Icon_minigender_1
  • 来自: 杭州699号
社区版块
存档分类
最新评论

RCP数据传输模型回顾

阅读更多
最近在做的项目,是一个C/S和B/S混合的项目,我主要负责设计开发框架部分,
最开始设计时,因时间仓促,没有细想,就草草上阵了,
现在项目快结束了,回过头来想想,还是有很多地方可以完善,这里说一下数据传输这一块。

因项目中B/S使用的是Struts2,所以C/S也通过Struts2提供的拦截器和Result扩展点进行了适配,
使得C/S数据传输序列化与反序列化对于业务逻辑透明化,目的是要让服务器端B/S和C/S写法一致。(客户端使用HttpClient实现)
Struts2整体设计还行,但确越来越臃肿,而且对RCP支持很不友好。

其实,C/S主流设计思路中,都是在Service层留出接口,并将接口部署到客户端,
中间通过RMI, Hessian, Burlap, WebService, HttpInvoker等任意方式生客户端Stub,
Stub实现中所有接口函数都远程代理服务器端相应Service实现,也就是客户端与服务器端对等体,
这样就可以通过接口“直接”调用服务器端函数,从而进行透明化数据传输。

B/S中的DWR也使用了这种方式。

这种设计的主要好处就是全部透明化,但将接口部署到客户端不是很方便,
而且服务器上的函数调用起来太方便,如果交互函数粒度较小,会使得业务逻辑向客户端倾斜,

保留Action门面,似乎还是很有必要的,这样可以保证客户端与服务器端交互粒度足够大,
但Action应该以数据为中心,而不是以控制为中心,
在RCP应用中,视图控制基本转移到客户端了,Action不应再对“跳转/切换”之类的过多关注,
WEB应用中的MVC框架,其返回值大多用来做控制,这也是它们不太适宜兼容RCP的问题所在。

按这个思路的设计如下:

客户端与服务器端共享:
Action接口:(在Action门面层实现透明化对等体)
public interface Action {

	Serializable execute(Serializable object);

}


服务器端:
实现Action接口:
public class XxxAction implements Action {

	private XxxService xxxService;

	public void setXxxService(XxxService xxxService) {
		this.xxxService = xxxService;
	}

	public Serializable execute(Serializable object) {
		// ...
	}
}

在spring的beans.xml中注册:
<bean id="xxxAction" class="com.xxx.action.XxxAction">
	<property name="xxxService" ref="xxxService"/>
</bean>


RCP应用客户端: (使用Swing/SWT做视图,序列化对象作传输)
在Java代码中,使用如:
// 返回的是代理,但看起来像拿到了服务器端的Action
Action xxxAction = ActionFacade.getAction("xxxAction");
// result和params为任意可序列化对象
Object result = xxxAction.execute(params);


WEB应用客户端: (使用ExtJS做视图,JSON作传输)
在JSP页面中,使用如:
<!-- name属性为action在beans.xml中注册的id号 -->
<ext:action var="xxxAction" name="xxxAction" />
<ext:script>
<!-- result和params为json对象 -->
var result = xxxAction.execute(params); 
</ext:script>


当然,服务器端拦截器的设计是必不可少的,
这种天然的截面,比AOP的自动代理用起来方便很多。
包括安全,检验,转换,控制都可以使用该截面统一实现。
拦截接口:
public interface ActionInterceptor {

	Serializable intercept(Action action, Serializable object);

}


另外,ThreadLocal的ActionContext也是必要的,
用于封装交互过程的附属信息等。
如:
ActionContext.getContext().getRequest();
ActionContext.getContext().getSession();


分享到:
评论
3 楼 莫莫摸 2019-01-08  
为什么不用dubbo
2 楼 javatar 2008-11-11  
leadyu 写道

为什么客户端要部署stub,我觉得是不是可以避免,如果客户端是java,那么能否通过jndi的方式去获取stub,现在在weblogic这样的中间件上,jndi已经不需要在本地部署实现类了。

是的,Stub实现不一定要部署,像Spring的HttpInvoker通过反射,在运行时生成Service接口的Stub代理实现,也很方便。
1 楼 leadyu 2008-11-04  
为什么客户端要部署stub,我觉得是不是可以避免,如果客户端是java,那么能否通过jndi的方式去获取stub,现在在weblogic这样的中间件上,jndi已经不需要在本地部署实现类了。

相关推荐

Global site tag (gtag.js) - Google Analytics