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 中显示更多页面的主要内容,如果未能解决你的问题,请参考以下文章
GWT 使用 RequestFactory 将 Objectify Cursor 从服务器传递到客户端,并在 DataGrid 中显示更多页面
GWT RequestFactory 并将服务器端更改传播到客户端