2011-08-29 39 views
1

我想創建一個應用程序來保存和檢索記錄到GAE服務器。我按照教程「部署到Google App Engine」http://code.google.com/webtoolkit/doc/latest/tutorial/appengine.html開始。GWT + GAE數據存儲密鑰和文本Java錯誤

我現在有了StockWatcher應用程序,但在我的應用程序中,我需要存儲一個可以很大(> 10KB)的字符串。我讀過我不能使用Java String類型來存儲大型字符串,而是需要使用Text數據類型。

我認爲通過文本,他們的意思是:com.google.appengine.api.datastore.Text,但它很高興確認這是正確的。 ???

無論如何,我無法讓文本正常工作。經過一番研究之後,似乎Key和Text只能在服務器代碼中使用,而不能在客戶端代碼中使用。看起來這是因爲源代碼不適用於這些類,而GWT需要源代碼在客戶端計算機上創建JavaScript代碼。至少,我目前的工作假設,爲什麼我收到以下錯誤:

21:52:52.823 [ERROR] [myapp] Line 15: The import com.google.appengine.api.datastore cannot be resolved 
21:52:52.951 [ERROR] [myapp] Line 103: Key cannot be resolved to a type 
21:52:53.011 [ERROR] [myapp] Line 106: Text cannot be resolved to a type 

我的共享文件夾使用以下字段中的一類。

共享/ MyDataRecord

@PrimaryKey 
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
private Key id; 

@Persistent 
private Text description; 

MyDataRecord類中的共享文件夾,因爲我想用在一個GET方法的返回而不是多個單獨的現場get方法發回的所有字段。以下是我在我的服務器使用MyDataRecord類/ DataServiceImpl.java類

public class DataServiceImpl extends RemoteServiceServlet implements DataService 
{ 
... 
    @Override 
    public MyDataRecord getDataRecord() throws NotLoggedInException 
    { 
    ... 

我見過使用非標準,第三方庫,像http://www.resmarksystems.com/code/一些發佈的解決方案建議。我無法安裝這個,但即使我可以,我更喜歡不同的解決方案。存儲文本必須是這樣一個常見的任務,我寧願使用被認爲是標準解決方案來解決這個問題。

我可以改變我的代碼,在多個get方法中返回每個字段,而不是返回一個MyDataRecord實例。但是,即使這種方法有效,隨着時間的推移,這將會顯着增加工作量並且難以維持。但是,如果這是通常所期望的,那麼這就是我要做的。

我想用GWT和GAE的最佳實踐來解決這個問題。一個簡單的例子或教程會走很長的路,但我找不到一個。

是否有示例程序/教程,顯示GWT認爲存儲和檢索大型字符串的最佳實踐?

我是一個GWT和GAE(以及網絡開發)的新手,請考慮在任何迴應,謝謝。

沒有蛇鯊請

+0

一個例子就是回答這個問題的最簡單的方法。 – Mitch

回答

2

可序列化的POJO。注意NotPersistent註釋的描述

package com.my.project.shared; 

@PersistenceCapable(identityType=IdentityType.APPLICATION,detachable="true") 
public class MyParent implements Serializable { 

    @PrimaryKey 
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) 
    private Long id; 
    @NotPersistent //Note the NotPersistent annotation. GAE won't persist this value in big table 
    private String description; 

} 

第二個POJO。注意包裝

package com.my.project.server; 

@PersistenceCapable(identityType=IdentityType.APPLICATION,detachable="true") 
public class MyChild implements Serializable{//Not really required to implement Serializable 

    @PrimaryKey 
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) 
    private Long id; 
    @Persistent 
    private Long parentID;//Reference to the MyParent 
    @Persistent 
    private Text description;//The actual value of the description variable. 
} 

請注意父代ID映射到子代。在檢索時,您需要確定哪個孩子屬於哪個父母。 在僞代碼 1)從DB 2裝入父)確定子對該父,並加載它 3)轉換child.description-> parent.description 4)現在你有一個完全構造父POJO這是串行化的。將其發送到用戶界面

只需在從UI返回到GAE的過程中顛倒過程即可。

+0

謝謝。這很明顯,呃。看看你的建議後,我可能會看到2個可能的解決方案,具體取決於我是否理解你的建議。這兩種解決方案都需要將班級分成兩類,但方式不同。 – Mitch

+0

一種方法是將所有隻能在服務器上使用的數據成員(如Text和Key)放入一個類中,從而對類進行分割。在另一個類中放置可以在客戶端和服務器上共享的所有數據成員。 – Mitch

+0

另一種方法是通過複製每個類中的所有數據成員來拆分類。就像第一種方法一樣,使用Long來存儲Key和String來將Text存儲在共享類中。共享類將是一個POJO,因爲它不會被持久化(No @Persistent Data)。您需要能夠在每個班級之間進行轉換。定義的客戶端接口(DataService.java和DataServiceAsync.java)將僅使用共享類。在讀取和寫入數據庫時​​,服務器的類(DataServiceImpl.java)實現將使用用戶定義的轉換。 – Mitch

1

1)定義NotPersistent場在您的序列化的POJO私人字符串描述 2)定義一個新的POJO服務器端這將有私人文本說明 3)當你堅持下去/加載原始POJO,檢索新的POJO並從文本描述中填充String描述

+0

那麼製作2班?一個是實現java.io.Serializable接口並且是一個POJO。另一個擁有@Persistent私人文本描述的類;並編寫在所有字段之間來回轉換的代碼?似乎有很多工作要維護2個課程,但如果這是預期的,那就是我要做的。謝謝。 – Mitch

+0

否。第二個類只有一個ID,映射到第一個類的UID和文本描述。無需擁有第一個POJO的完整副本。只是抽象的文字 – maneesh

+0

好吧,我不明白你在說什麼。你能指出一個示例程序/教程,顯示你在說什麼嗎? – Mitch