通过GWT RPC获取大数据遇阻,求适配GWT-2.6.1的替代方案
Hey there! Let's dive into solutions for your large data loading issue with GWT RPC and Objectify, given your stack of gwt-2.6.1 and appengine-1.9.6. Here are practical, actionable approaches you can implement:
1. Cursor-Based Pagination (Chunked Loading)
Forget loading everything at once—split your data into manageable chunks using Objectify's cursor support (way better than offset() which can skip items if data changes between requests). This keeps each RPC payload small and avoids timeouts.
- Server-side example:
Query<YourEntity> query = ofy().load().type(YourEntity.class); // If client sent a cursor from previous request, resume from there if (cursorString != null) { query = query.startAt(Cursor.fromWebSafeString(cursorString)); } QueryResultIterator<YourEntity> iterator = query.limit(50).iterator(); // 50 items per chunk List<YourEntity> chunk = Lists.newArrayList(iterator); String nextCursor = iterator.getCursor().toWebSafeString(); // Return chunk + nextCursor to client - On the client, add a "Load More" button or auto-load chunks as the user scrolls, using the cursor to fetch the next set of data.
2. Swap GWT RPC for RequestFactory
RequestFactory is GWT's more efficient alternative to RPC—it uses a compact wire format and supports partial entity loading (only fetch the fields you actually need). It plays nicely with Objectify too, so you won't have to overhaul your data layer.
- Define entity proxies that mirror your Objectify entities, then create request interfaces to fetch data. This cuts down payload size significantly compared to full RPC serialization.
3. Enable Payload Compression
Shrink the data sent over the wire with compression:
- In your
gwt.xml, turn on delta payloads (only send changed data if re-fetching):<set-property name="gwt.rpc.deltaPayload" value="true"/> - Configure App Engine to serve gzipped content: Add rules to
appengine-web.xmlfor static content, and on the server side, check theAccept-Encodingheader to return gzipped responses for dynamic RPC calls.
4. Use Projection Queries
If you don't need every field in your entities, use Objectify's projection queries to fetch only the necessary fields. This reduces both server-side processing time and payload size.
- Example:
List<YourEntity> partialEntities = ofy().load().type(YourEntity.class) .project("name", "timestamp", "value") // Only fetch these fields .list();
5. Pre-Aggregate Data for Analytical Use Cases
If you're loading data for reports or dashboards, pre-compute summary entities on the server (using cron jobs or task queues). Instead of fetching thousands of raw entities, fetch a handful of pre-aggregated summaries—this will be exponentially faster.
6. Shift to REST + JSON
If you're open to moving beyond GWT RPC, build a REST endpoint on App Engine (using servlets or JAX-RS) that returns JSON data. On the GWT client, use RequestBuilder to make HTTP calls and parse JSON with GWT's built-in parser. JSON payloads are often smaller than GWT RPC's serialized objects, and this approach gives you more flexibility for future changes.
内容的提问来源于stack exchange,提问作者Anil Pal

