GWT 使用 RequestFactory 将 Objectify Cursor 从服务器传递到客户端,并在 DataGrid 中显示更多页面

Posted

技术标签:

【中文标题】GWT 使用 RequestFactory 将 Objectify Cursor 从服务器传递到客户端,并在 DataGrid 中显示更多页面【英文标题】:GWT pass Objectify Cursor from Server to Client with RequestFactory and show more pages in DataGrid 【发布时间】:2012-06-18 23:59:27 【问题描述】:

我是游标新手,有以下方法:

public List<Venue> findPage(Subject subject, Objectify ofy, int pageSize) 
  final Business business = (Business) subject.getSession().getAttribute(BUSINESS_ATTRIBUTE);
  final Query<Venue> query = ofy.query(Venue.class).filter(BUSINESS_ATTRIBUTE, business);
  final String encodedCursor = (String) subject.getSession().getAttribute(VENUE_CURSOR_CONDITION);
  if (encodedCursor != null) 
    query.startCursor(Cursor.fromWebSafeString(encodedCursor));
  
  final QueryResultIterator<Key<Venue>> iterator = query.fetchKeys().iterator();
  final List<Key<Venue>> data = new ArrayList<Key<Venue>>(pageSize);
  boolean more = false;
  for (int i = 0; i < pageSize && (more = iterator.hasNext()); i++) 
    data.add(iterator.next());
  
  subject.getSession().setAttribute(VENUE_CURSOR_CONDITION, iterator.getCursor().toWebSafeString());
  return get(ofy, data);

其中get是下面的方法

public <T> List<T> get(Objectify ofy, List<Key<T>> keys) 
  if (keys == null) 
    return null;
  
  final Map<Key<T>, T> map = ofy.get(keys);
  final List<T> list = new ArrayList<T>();
  for (T t : map.values()) 
    list.add(t);
  
  return list;

现在,这就是我目前正在做的事情 - 这有点老套。我正在使用 Apache Shiro 来跟踪用户的会话 - 在用户的会话中,我保留最后一个使用的光标 - 如果用户导航离开页面,我将光标设置为 false (显然 - 这非常非常脆弱,因为它需要每个方法都有一个代码使最后一个光标无效)。

现在,我被抓到了。我做了一个简单的 HasCursor 接口,并且打算将一个带有 Cursor 的 List 传回给客户端——唯一的问题是 RequestFactory 只能处理从服务器到客户端的某些类型的传递——这种自定义类型不是其中之一。那么,现在使用 GWT RequestFactory - 是否有一种将 Objectify Cursor 从服务器传递到客户端的好方法?

另外 - 我遇到的另一个问题 - 如果我用这些数据填充 DataGrid,它会在网格中显示数据很好 - 但就是这样 - 寻呼机说 1-25 出 25。所以,我是什么想知道的是,您实际上如何告诉 DataGrid 服务器上有更多可用数据。我有点困惑,因为似乎没有很多可用的文档/示例。

非常感谢


对于遇到此问题的其他任何人,我找到了其中一部分的答案 - 我完全忘记了 ValueProxies,它允许您映射标准 Java bean 以使用 RequestFactory 从服务器返回到客户端。

不幸的是,您不能将泛型与 ValueProxies 一起使用,因此我必须为每个单独的类型创建一个 ListCursor 包装器。

这是代理:

@ProxyFor(value = VenueListCursorWrapper.class)
public interface VenueListCursorWrapperProxy extends ValueProxy 

  List<VenueProxy> getVenues();

  String getCursor();

  boolean isMoreAvailable();

  void setVenues(List<VenueProxy> venues);

  void setCursor(String cursor);

  void setMoreAvailable(boolean moreAvailable);

这是服务器上的更新方法:

public VenueListCursorWrapper findPage(Subject subject, Objectify ofy, int pageSize, String cursor) 
  final Business business = (Business) subject.getSession().getAttribute(BUSINESS_ATTRIBUTE);
  final Query<Venue> query = ofy.query(Venue.class).filter(BUSINESS_ATTRIBUTE, business);
  if (cursor != null) 
    query.startCursor(Cursor.fromWebSafeString(cursor));
  
  final QueryResultIterator<Key<Venue>> iterator = query.fetchKeys().iterator();
  final List<Key<Venue>> data = new ArrayList<Key<Venue>>(pageSize);
  boolean more = false;
  for (int i = 0; i < pageSize && (more = iterator.hasNext()); i++) 
    data.add(iterator.next());
  
  return new VenueListCursorWrapper(get(ofy, data), iterator.getCursor().toWebSafeString(), more);

所以 - 这就是它的一部分 - 我还没有完全弄清楚如何做的一件事是正确设置寻呼机 - 我想显示寻呼机中的项目总数,以便您浏览它,但我不确定如何执行此操作 - 如果我找到解决方案,我会发布它

【问题讨论】:

【参考方案1】:

您可以将Cursor 转换为可序列化的字符串——实际上您已经使用了它:iterator.getCursor().toWebSafeString()

只需将序列化的游标(= 一个字符串)连同所有其他列表数据一起返回给客户端,并在下一个请求中将其作为参数提供。

Optonaly 在fragment identifier,又名GWT history token 中使用它,以便用户实际上可以为列表中的特定页面添加书签(取决于用例,如果列表数据没有太大变化则有意义)。

【讨论】:

嗯 - 这就是问题所在 - 使用 RequestFactory 我不知道如何返回它 - 使用 RequestFactory 似乎我无法将两者一起返回 - 从请求工厂站点它说我只能返回原语、盒装原语、其他(枚举、大整数、大十进制、日期)、值/实体和集合/列表的代理 - 我不知道如何用列表取回字符串,因为我可以'不传回包含列表和字符串的对象

以上是关于GWT 使用 RequestFactory 将 Objectify Cursor 从服务器传递到客户端,并在 DataGrid 中显示更多页面的主要内容,如果未能解决你的问题,请参考以下文章

RequestFactory 与服务层

GWT 使用 RequestFactory 将 Objectify Cursor 从服务器传递到客户端,并在 DataGrid 中显示更多页面

GWT RequestFactory 性能

GWT RequestFactory 并将服务器端更改传播到客户端

GWT requestfactory 验证外部服务器上的实体

GWT 2.6 - RequestFactory Locator 找不到类似的域方法