2011-08-29 2 views
1

Je voudrais créer une application qui enregistre et récupère des enregistrements sur le serveur GAE. J'ai suivi le tutoriel "Déploiement sur Google App Engine" http://code.google.com/webtoolkit/doc/latest/tutorial/appengine.html pour commencer.GWT + GAE datastore Clé et texte Erreur Java

J'ai l'application StockWatcher qui fonctionne maintenant, mais dans mon application, j'ai besoin de stocker une chaîne qui peut être grande (> 10 Ko). J'ai lu que je ne peux pas utiliser un type Java String pour stocker de grandes chaînes et que j'ai besoin d'utiliser le type de données Text à la place.

Je pense que par Text, ils signifient: com.google.appengine.api.datastore.Text, mais ce serait bien de confirmer que c'est correct. ??? Quoi qu'il en soit, je n'arrive pas à faire fonctionner Text. Après quelques recherches, il apparaît que les types Key et Text ne peuvent être utilisés que dans le code du serveur et non dans le code client. Il semble que cela soit dû au fait que le code source n'est pas disponible pour ces classes et GWT a besoin de la source pour créer le code JavaScript sur l'ordinateur du client. Au moins que mon hypothèse de travail actuelle la raison pour laquelle je reçois les erreurs suivantes:

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 

J'utilise les champs suivants dans une classe dans un dossier partagé.

partagé/MyDataRecord

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

@Persistent 
private Text description; 

classe MyDataRecord dans un dossier partagé parce que je voulais utiliser pour renvoyer tous les champs dans un retour de méthode get plutôt que plusieurs champ individuel obtenir des méthodes. Voici comment j'utilise la classe MyDataRecord dans mon serveur/DataServiceImpl.java classe

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

J'ai vu des solutions affichées suggèrent d'utiliser non standard, les bibliothèques 3ème partie, comme http://www.resmarksystems.com/code/. Je ne pouvais pas installer celui-ci, mais même si je le pouvais, je préférerais une solution différente. Stockage de texte doit être une tâche si commune que je préfère résoudre ce problème en utilisant ce qui est considéré comme une solution standard.

Je pourrais changer mon code pour retourner chaque champ dans plusieurs méthodes get au lieu d'un seul retour d'une instance MyDataRecord. Cependant, même si cela fonctionne, ce serait beaucoup plus de travail et plus difficile à maintenir avec le temps. Cependant, si c'est ce qui est normalement prévu, alors c'est ce que je ferai.

Je voudrais résoudre ce problème en utilisant les meilleures pratiques de GWT et de GAE. Un exemple simple ou un tutoriel irait un long chemin, mais je ne peux pas en trouver un. Existe-t-il des exemples de programmes/tutoriels qui montrent ce que GWT considère comme les meilleures pratiques pour stocker et récupérer des chaînes de caractères volumineuses? Je suis un débutant avec GWT et GAE (ainsi que le développement web), s'il vous plaît considérer cela dans les réponses, merci.

Non Snark S'il vous plaît

+0

Un exemple serait la façon la plus simple d'y répondre. – Mitch

Répondre

2

Le POJO sérialisable.Notez l'annotation NotPersistent pour la description

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; 

} 

Le deuxième POJO. Notez le package

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. 
} 

Notez l'ID parent mappé dans l'enfant. Pendant la récupération, vous devrez identifier quel enfant appartient à quel parent. En pseudo code 1) Charger le parent de la base de données 2) Identifier l'enfant pour ce parent et le charger 3) Convertir child.description-> parent.description 4) Vous avez maintenant un POJO parent entièrement construit qui est sérialisable. Envoyez-le à l'interface utilisateur

Il vous suffit d'inverser la procédure au retour de l'interface utilisateur à GAE.

+0

Merci. C'est clair. Après avoir regardé votre suggestion, je peux voir 2 solutions possibles, selon si je comprends ce que vous suggérez. Les deux solutions nécessitent de diviser la classe en 2 classes, mais de différentes manières. – Mitch

+0

Dans un sens, divise la classe en plaçant tous les membres de données qui ne peuvent être utilisés sur le serveur, comme le texte et la clé, dans une classe. Dans l'autre classe, placez tous les membres de données qui peuvent être partagés sur le client et le serveur. – Mitch

+0

L'autre façon est de diviser les classes en dupliquant tous les membres de données dans chaque classe. Tout comme la première façon, utilisez un long pour stocker une clé et une chaîne pour stocker du texte dans la classe partagée. La classe partagée sera un POJO car elle ne sera pas persistée (pas de données @Persistent). Vous devrez être capable de convertir entre chaque classe. Les interfaces du client défini (DataService.java et DataServiceAsync.java) utiliseront uniquement les classes partagées. L'implémentation de la classe du serveur (DataServiceImpl.java) utilisera les conversions définies par l'utilisateur lors de la lecture et de l'écriture dans la base de données. – Mitch

1

1) Définir un champ NotPersistent dans votre sérialisable POJO private String Description 2) Définir un nouveau POJO sur du côté serveur qui aura la description privée de texte 3) Lorsque vous persistez/charger le POJO d'origine, récupérer le nouveau POJO et renseigner la description de la chaîne à partir de la description du texte

+0

Alors faites 2 classes? Celui qui implémente l'interface java.io.Serializable et est un POJO. Une autre classe qui a la description textuelle privée @Persistent; et écrire du code qui convertit à la fois en arrière et en avant entre tous les champs? On dirait que beaucoup de travail pour maintenir 2 classes, mais si c'est ce qui est attendu, c'est ce que je vais faire. Merci. – Mitch

+0

No. La deuxième classe avec seulement un ID qui correspond à l'UID de la 1ère classe et la description du texte. Pas besoin d'avoir une copie complète du 1er POJO. Juste résumé le texte – maneesh

+0

D'accord, je ne comprends pas ce que vous dites. Pouvez-vous pointer vers un exemple de programmes/tutoriels qui montre ce que vous dites? – Mitch