GWT手动序列化服务器上​​的域对象

时间:2012-03-17 18:40:38

标签: java gwt gwt2 requestfactory autobean

我的GWT应用程序在加载时首先要做的是通过RequestFactory从服务器请求当前登录用户。这会阻止,因为我需要用户的属性才能知道如何继续。这只需要< 500毫秒,但在这段时间内应用程序被阻止真的让我感到很恼火。生成jsp时我已经在服务器上安装了User,那么为什么不将序列化的User添加到jsp中并完全消除这个请求呢?

我有两个问题阻止我这样做:

  • 我需要将User转换为UserProxy
  • 我需要以一种易于GWT反序列化的方式序列化UserProxy。

我还没有找到一个做好#1的好方法。这个逻辑似乎埋没在ServiceLayerDecorator中,没有一种简单的方法可以隔离?我可能在这里错了。

第二个似乎更容易通过ProxySerializer但是当我在服务器上时如何获得requestfactory?您无法在服务器上呼叫GWT.create

我一直在研究AutoBeans,但这并没有处理上面的#1。我的UserProxy引用了我想要维护的其他EntityProxy的集合。

4 个答案:

答案 0 :(得分:5)

如果为代理创建AutoBeanFactory,则可以使用AutoBeans:

  • 将用户转换为UserProxy: 创建服务器端RequestFactory并调用相同的正常请求。响应将包含UserProxy(但在服务器上)。

  • 序列化UserProxy:

    AutoBean<UserProxy> bean = AutoBeanUtils.getAutoBean(receivedUserProxy);

    String json = AutoBeanCodex.encode(bean).getPayload();

  • 要在客户端反序列化UserProxy:

    AutoBean<UserProxy> bean = AutoBeanCodex.decode(userAutoBeanFactory, UserProxy.class, json);

在服务器上创建进程内RequestFactory(tutorial):

public static <T extends RequestFactory> T create( Class<T> requestFactoryClass ) {
  ServiceLayer serviceLayer = ServiceLayer.create();
  SimpleRequestProcessor processor = new SimpleRequestProcessor( serviceLayer );
  T factory = RequestFactorySource.create( requestFactoryClass );
  factory.initialize( new SimpleEventBus(), new InProcessRequestTransport(processor) );
  return factory;
}

答案 1 :(得分:3)

如果您能够User implements UserProxy,也可以使用AutoBeans。它可以工作,因为Proxies是与getter / setter的接口:

interface UserFactory implements AutoBeanFactory
{
  AutoBean<UserProxy> user(UserProxy toWrap); // wrap existing instance in an AutoBean
}

然后在服务器上,您可以创建autobean并序列化为json:

UserFactory factory = AutoBeanFactorySource.create(UserFactory.class)
AutoBean<UserProxy> userProxyBean = factory.user( existingUserPojo );

// to convert AutoBean to JSON
String json = AutoBeanCodex.encode(userProxyBean).getPayload();

在客户端上,您只需使用AutoBeanCodex.decode将JSON反序列化为bean

答案 2 :(得分:1)

您无法在服务器(或任何真正的JVM)上调用GWT.create,但在许多情况下,您可以调用专为服务器使用而设计的JVM兼容方法。在这种情况下,请查看RequestFactorySource.create

让服务器从自身读取并使用RequestFactory打印数据可能有点麻烦 - 这是一个如何工作的演示示例(使用gwt 2.4,主分支对于2.3左右具有相同的功能) )https://github.com/niloc132/tvguide-sample-parent/blob/gwt-2.4.0/tvguide-client/src/main/java/com/acme/gwt/server/TvViewerJsonBootstrap.java - 你所追求的并不完全相同,但也可以使用同样的想法来填充可以在客户端中读取的代理商店中的字符串(在此处https://github.com/niloc132/tvguide-sample-parent/blob/gwt-2.4.0/tvguide-client/src/main/java/com/acme/gwt/client/TvGuide.java )。

基本思想是创建一个请求(包括id,invocations和with()参数,以便代理构建器以一致的方式制作所有正确的部分),并将其传递给SimpleRequestProcessor实例,然后将通过它通常的服务器块运行它。 (任何实体管理系统可能仍应将实体缓存以避免额外查找,否则您需要对SRP内部工作的一些工作进行建模。)包含ProxySerializer的{​​{1}}期望拥有从服务器发送的完整RF消息,因此需要正确完成相当多的消息簿记。

答案 3 :(得分:1)

我在GWT上找到了答案Google Group。所有积分都转到Nisha Sowdri NM

服务器端编码:

DefaultProxyStore store = new DefaultProxyStore();
ProxySerializer ser = requests.getSerializer(store);
final String key = ser.serialize(userProxy);
String message = key + ":" + store.encode();

客户端解码:

String[] parts = message.split(":", 2);
ProxyStore store = new DefaultProxyStore(parts[1]);
ProxySerializer ser = requests.getSerializer(store);
UserProxy user = ser.deserialize(UserProxy.class, parts[0]);