2012-10-09 110 views
1

我想使用App Engine的RPC和GWT(它是一個應用程序引擎連接的項目)實現分頁。存儲光標的App引擎分頁

如何將查詢結果和網頁安全遊標對象從RPC傳遞給GWT客戶端?

我見過使用servlet的例子,但我想知道如何在沒有servelt的情況下做到這一點。

我考慮過在使用memcache的服務器上緩存遊標,但我不確定這是否合適,或者應該用什麼作爲鍵(會假設我會假設會話標識符,但我不確定這些是如何處理的在App Engine上)。

鏈接到示例項目將是太棒了,我一直無法找到任何。

回答

2

好的,所以最好的方法是將遊標作爲字符串存儲在客戶端上。

要做到這一點,你必須創建一個包裝類,是運輸的,所以你可以把它傳遞迴通過RequestFactory客戶端,可容納結果列表和光標的字符串。要做到這一點,你創建一個普通的POJO,然後代理它。

這裏的代碼是什麼樣子的POJO:

public class OrganizationResultsWrapper { 

    public List<Organization> list; 
    public String webSafeCursorString; 

    public List<Organization> getList() { 
     return list; 
    } 

    public void setList(List<Organization> list) { 
     this.list = list; 
    } 

    public String getWebSafeCursorString() { 
     return this.webSafeCursorString; 
    } 

    public void setWebSafeCursorString(String webSafeCursorString) { 
     this.webSafeCursorString = webSafeCursorString; 
    } 
} 

爲代理:

@ProxyFor(OrganizationResultsWrapper.class) 
public interface OrganizationResultsWrapperProxy extends ValueProxy{ 

    List<OrganizationProxy> getList(); 
    void setList(List<OrganizationProxy> list); 

    String getWebSafeCursorString(); 
    void setWebSafeCursorString(String webSafeCursorString); 

} 

設置你的服務,並requestFactory使用POJO分別代理

// service class method 
@ServiceMethod 
public OrganizationResultsWrapper getOrganizations(String webSafeCursorString) { 
    return dao.getOrganizations(webSafeCursorString); 
} 

// request factory method 
Request<OrganizationResultsWrapperProxy> getOrganizations(String webSafeCursorString); 

然後確保並運行RPC嚮導,以便您的驗證過程,否則運行喲你會在服務器上得到一個請求上下文錯誤。

下面是我的數據訪問類的實現:

public OrganizationResultsWrapper getOrganizations(String webSafeCursorString) { 
    List<Organization> list = new ArrayList<Organization>(); 
    OrganizationResultsWrapper resultsWrapper = new OrganizationResultsWrapper(); 

    Query<Organization> query = ofy().load().type(Organization.class).limit(50); 

    if (webSafeCursorString != null) { 
     query = query.startAt(Cursor.fromWebSafeString(webSafeCursorString)); 
    } 

    QueryResultIterator<Organization> iterator = query.iterator(); 
    while (iterator.hasNext()) { 
     list.add(iterator.next()); 
    } 

    resultsWrapper.setList(list); 
    resultsWrapper.setWebSafeCursorString(iterator.getCursor().toWebSafeString()); 

    return resultsWrapper; 
} 
0

第二選擇是保存webSafeCursorString在內存緩存,因爲你已經提到。

我的想法是這樣的:

  1. 客戶端發送請求總是像這樣 「getMyObjects(對象... myParams,詮釋的maxResults,字符串clientPaginationString)」。該clientPaginationString是獨創像圖所示

  2. 服務器收到請求,並眺望內存緩存如果有一個關鍵clientPaginationString

    1. 如果服務器覺得沒有什麼

      一個webSafeCursorString,他創建查詢和保存將webSafeCursorString轉換爲以clientPaginationString爲關鍵字的memcache。 - >返回結果

    2. 如果服務器發現他重新開始查詢它的webSafeCursorString並返回結果

的問題是如何清潔內存緩存,以及如何找到一個獨特的clientPaginationString:

一個唯一的clientPaginationString應該是當前UserId +當前查詢的參數+ timestemp。這應該工作得很好!

我真的想不出一個簡單的方法來清理memcache,但我認爲我們根本不需要清理它。 我們可以在包含地圖的WebSafeCursor-Class中存儲所有webSafeCursorStrings和timestemps + params + userid,並將所有這些存儲在memcache中,並在一段時間內清理此類類(時間戳較老的時間...)。

我能想到的一個改進就是使用在服務器上創建的鍵(userSessionId + servicename + servicemethodname + params)將webSafeCursorString保存在memcache中。然而,重要的是,如果客戶對新查詢感興趣(memcache被覆蓋)或想要下一個分頁結果(從memcache獲取webSafeCursorString),則客戶端會發送一條信息。重新加載頁面應該可以工作。在瀏覽器中的第二個水龍頭將是一個問題,我認爲...

你會說什麼?