Mails über JavaMail abrufen und im GWT Client anzeigen

Improof

Erfahrenes Mitglied
Hi,

das sieht an sich ja schon mal super aus, vom Code her :)

Dein Problem liegt darin, dass du externe Libraries nicht nur zum Eclipse Build Path hinzufügen musst: Damit deine Webapllikationen diese auch findet, müssen sie im war/WEB-INF/lib Verzeichnis deiner Apllikation liegen! Dann sollte alles soweit funktionieren ;)

Gruß
Daniel
 

Kumaro

Mitglied
Oh man, das war ja mal nen super Anfängerfehler :D. Danke!
Ich dachte irgendwie, das die Lib ja nichts mit dem Client zu tun hat und daher auch nicht in das Verzeichnis muss...aber das war ja offensichtlich falsch ^^.

Gruß
 

Improof

Erfahrenes Mitglied
Hi,

haha ja bitte :D Ob Client oder Server Code ist in dem Fall völlig egal: Client Code aus den Libraries wird mit ins JavaScript generiert (sofern möglich, z.B. bei anderen GWT Modulen) und der Rest bleibt als Java für den Server verfügbar ;)

Gruß
 

Improof

Erfahrenes Mitglied
So, jetzt bin ichs nochmal:

Ich hab grad deinen Client Code genauer angeschaut
Java:
package webmail.client;
public class MessageResponse extends JsonBaseResponse{
    protected MessageResponse(){}
    public final native String getContent()
        /*{ return this.content; } */;
 
}
public class JsonBaseResponse extends JavaScriptObject {
    protected JsonBaseResponse(){}
    public static final native <T extends JsonBaseResponse> T getResponse(String json)
        /*-{ return eval('(' + json + ')'); } */;
}

Du musst da bei den nativen Methoden besonders aufpassen, weil deine Klammern falsch sind! Da fehlt (bis auf ein mal) ein "-".

Bei dir: "/*{" bzw. "}*/"
Eigentlich richtig: "/*-{" und "}-*/;}"

Ich weiß jetzt nicht mal was Eclipse hier dann macht (ob's nen Fehler anzeigt oder nicht), da /* und */ ja in Java eigentlich Kommentarzeichen sind...
Aber spätestens zur Laufzeit bekommst du da nen Fehler!

Ansonsten siehts wie gesagt gut aus :)

Gruß
Daniel
 

Kumaro

Mitglied
Hi Daniel, danke ich hab das mal nachgebessert. Ich konnte mir bisher auch nicht erklären was die Kommentare bewirken sollen ^^. Aber scheinbar ist es ja JavaScript Code.
Könntest du bitte mal kurz erklärenm was genau der JavaScript Code in der Base Klasse bewirkt? So richtig steig ich da nicht durch.

public abstract class JsonBaseResponse extends JavaScriptObject
{
protected JsonBaseResponse() { }

public static final native <T extends JsonBaseResponse> T getResponse(String json) /*-{
return eval('(' + json + ')');
}-*/;
}



Vielen Dank :)
 

Improof

Erfahrenes Mitglied
Hi Kumaro,

ja der Code ist auch etwas komplizierter, wusste Anfangs auch nicht so genau, was das macht :D
Aber im Grunde genommen ist es ja nicht viel:

Ich weiß nicht, ob du schon mal Methoden mit generischem Rückgabetyp programmiert hast. Das sieht dann nämlich genau so aus, wie bei der getResponse() Methode. Normalerweise hat man allerdings keine statischen Methoden, die generisch sind. Das schaut dann ungefähr so aus:

Java:
public <T extends Object> T testMethode(Class<T> type)
{
    ...
}

Was sagt das nun aus? Eigentlich ist es ganz einfach: Der verwendete generische Typ ist <T extends Object> und kann daher alles sein, da ja alles von Object erbt. Der Rückgabetyp der Methode ist T, also genau der generische Typ. Und über den Parameter legst du fest, welcher Typ das ist. Bei Klassen mit generischen Typ (so wie z.B. List / ArrayList) ist der Typ dabei übergreifend in der Klasse deklariert. Bei der Methode gilt er eben auch nur da.
Ein Aufruf bei dem du einen Integer als Rückgabe erwartest sieht dann in etwa so aus:

Java:
int result = testMethode(Integer.class);

Bei der getResponse() Methode fehlt nun aber der Type-Parameter! Dafür haben wir eine andere Besonderheit: Die Methode ist statisch. Damit ist der Rückgabetyp immer die Klasse, von der aus du die Methode aufrufst (wie oben schon beschrieben, ich poste es hier nochmal):
  • MessageResponse.getResponse(hier-json-string-einfügen) -> gibt eine MessageResponse zurück.
  • TestResponse.getResponse(hier-json-string-einfügen) -> gibt eine TestResponse zurück
  • BlablaResonse.getResponse(...) -> ...
  • ...

Soviel zum Methodenkopf. Nun zum Rest (ist ja nur noch eine Zeile JavaScript ;)).
Der Code den wir uns nun ansehen müssen:

Javascript:
return eval ('(' + json + ')');

Erstmal ein Wort zu dem nativen Aufruf von Methoden über JSNI (JavaScript Native Interface) - denn nichts anderes machen wir hier:
Die Parameter die du aus der Java-Welt übergibst sind auch in der JavaScript-Welt unter gleichem Namen verfügbar. Es gibt ein paar Einschränkungen, was für Typen du genau übergeben kannst. Näheres dazu findest du hier: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html#sharing.

Für uns ist nur wichtig: Der Parameter 'json' heißt auch in JavaScript 'json' und beinhaltet unseren JSON-String. Der Aufruf der eval() Methode ist das nächste:
Jeder Browser kann nativ JavaScript Objekte aus JSON-Strings erstellen. Und zwar genau mit dieser Methode. Also erzeugt uns ein Aufruf von eval() eben unser gewünschtes JavaScript-Objekt. Warum da um den String die Klammern sein müssen weiß ich nicht, aber ich hab auch nur auf google lange gesucht, wie man sowas macht und anscheinend geht es manchmal nicht ohne diese Klammern...ich hatte jedenfalls so mit den Klammern in Google Chrome, Firefox und IE noch nie Probleme ;)

Das erstellte JavaScript Objekt geben wir mit return wieder in unsere Java-Welt zurück. Dort können wir mit weiteren nativen Methoden (wie z.B. deine getContent()) auf die Werte zugreifen, die im eigentlichen Objekt gespeichert sind. Zur Laufzeit ist dass dann natürlich alles JavaScript, der GWT-Compiler macht ja aus deinem Java Code nichts anderes. Aber programmieren musst du es eben so ;)


Ich hoffe das war verständlich, bei Rückfragen, einfach hier rein posten :)

Gruß
Daniel