Post on 28-May-2015
description
transcript
DAS GOOGLE WEB TOOLKIT
Malte Wessel
GRUNDLAGEN
WAS IST DAS GOOGLE WEB TOOLKIT?
• Java-Framework zur Entwicklung von Webanwendungen
• komplette Entwicklung in Java
• Kommunikation von Client und Server durch Ajax
WAS IST AJAX?
• Asynchronous JavaScript and XML
• Konzept zum Asynchronen Informationsaustausch zwischen Client und Server mittels JavaScript
• Arbeitet mit der XMLHttpRequest-API
• Informationsaustausch z.B. von Html, Xml oder JSON
• Manipulation des DOM (Document Object Model) durch JavaScript
Server
Client(Browser)
Anf
rage
Anfrage des Clients an den Server. Geforderte Seite z.B. http://www.studivz.net
Ant
wor
t
Server verarbeitet Anfrage und schickt die Informationen in Form von Html-, CSS, JavaScript-, und Bild-Dateien
KLASSISCHE SERVER-ANFRAGE(BEISPIEL: STUDIVZ)
SERVER-ANFRAGE MITTELS AJAX
Server
Client(Browser)
Anf
rage
JavaScript-EngineKontinuierliche Aktualisierung
der Chat-Nachrichten(JavaScript-Aufruf)
(BEISPIEL: STUDIVZ/PLAUDERKASTEN)
Ant
wor
t
Server antwortet mit Html-, JavaScript- oder XML-Dateien
JavaScript-Engine verarbeitet empfangene Informationen
und präsentiert sie im Browser (DOM-Manipulation)
Ausgangspunkt:Plauderkasten wurde geladen. Alle Html-, CSS- und Bild-Dateien sind in Verwendung
DAS GOOGLE WEB TOOLKIT
WARUM DAS GOOGLE WEB TOOLKIT?
• Erleichtert das Erstellen von komplexen Webanwendungen
• Server und Client (!) werden in Java entwickelt
• Beseitigt Inkompatibilitäts-Probleme
• Java-Entwicklungsumgebung
ARCHITEKTUR DES GWT
ARCHITEKTUR DES GWT
ARCHITEKTUR DES GWT
ARCHITEKTUR DES GWT
PROJEKTSTRUKTUR
• GWT-Anwendungen werden grundsätzlich in Projekten organisiert
• Projektstruktur baut auf Java-Paketen auf
• Aufteilung in clientseitigen Code, serverseitigen Code, Ressourcen und Module
MODULE
<?xml version="1.0" encoding="UTF-8"?><module rename-to='referat'> <!-- Inherit the core Web Toolkit stuff. --> <inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change --> <!-- the theme of your GWT application by uncommenting --> <!-- any one of the following lines. --> <inherits name='com.google.gwt.user.theme.standard.Standard'/> <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> --> <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<!-- Specify the app entry point class. --> <entry-point class='com.referat.client.Referat'/>
<!-- Specify the paths for translatable code --> <source path='client'/> <source path='shared'/>
</module>
ERSTELLEN VON BENUTZEROBERFLÄCHEN
• Verwendung von Widgets
• Große Anzahl an vorgefertigten Widgets
• Kombination von Widgets zu eigenen Widgets
• Funktionieren ähnlich wie Swing-Komponenten
• Cross-Browser Kompatibilität
• GUI-Gestaltung wird auf Java-Oberflächenkonzept verlagert
WIDGET BEISPIELE
IMPLEMENTIERUNG VON WIDGETS
public class MyFileUpload implements EntryPoint { public void onModuleLoad() { // Widget-Objekte erstellen VerticalPanel vPanel = new VerticalPanel();
FileUpload fileUpload = new FileUpload(); Button uploadButton = new Button("Upload File"); // Widgets „zusammenfügen“ vPanel.add("Select a file:"); vPanel.add(fileUpload); vPanel.add(new HTML("<br>")); vPanel.add(uploadButton);
// Widgets in Html-Seite einbinden RootPanel.get("uploadFieldContainer").add(vPanel); }}
IMPLEMENTIERUNG VON WIDGETS
public class MyFileUpload implements EntryPoint { public void onModuleLoad() { // Widget-Objekte erstellen VerticalPanel vPanel = new VerticalPanel();
FileUpload fileUpload = new FileUpload(); Button uploadButton = new Button("Upload File"); // Widgets „zusammenfügen“ vPanel.add("Select a file:"); vPanel.add(fileUpload); vPanel.add(new HTML("<br>")); vPanel.add(uploadButton);
// Widgets in Html-Seite einbinden RootPanel.get("uploadFieldContainer").add(vPanel); }}
IMPLEMENTIERUNG VON WIDGETS
public class MyFileUpload implements EntryPoint { public void onModuleLoad() { // Widget-Objekte erstellen VerticalPanel vPanel = new VerticalPanel();
FileUpload fileUpload = new FileUpload(); Button uploadButton = new Button("Upload File"); // Widgets „zusammenfügen“ vPanel.add("Select a file:"); vPanel.add(fileUpload); vPanel.add(new HTML("<br>")); vPanel.add(uploadButton);
// Widgets in Html-Seite einbinden RootPanel.get("uploadFieldContainer").add(vPanel); }}
IMPLEMENTIERUNG VON WIDGETS
public class MyFileUpload implements EntryPoint { public void onModuleLoad() { // Widget-Objekte erstellen VerticalPanel vPanel = new VerticalPanel();
FileUpload fileUpload = new FileUpload(); Button uploadButton = new Button("Upload File"); // Widgets „zusammenfügen“ vPanel.add("Select a file:"); vPanel.add(fileUpload); vPanel.add(new HTML("<br>")); vPanel.add(uploadButton);
// Widgets in Html-Seite einbinden RootPanel.get("uploadFieldContainer").add(vPanel); }}
IMPLEMENTIERUNG VON WIDGETS
Das DOM nach Manipulation durch vom GWT generierten JavaScript-Code
IMPLEMENTIERUNG VON WIDGETS
Das DOM nach Manipulation durch vom GWT generierten JavaScript-Code
IMPLEMENTIERUNG VON WIDGETS
Das DOM nach Manipulation durch vom GWT generierten JavaScript-Code
IMPLEMENTIERUNG VON WIDGETS
Das DOM nach Manipulation durch vom GWT generierten JavaScript-Code
EVENTS & LISTENER
• Listener registrieren z.B. Aktionen des Benutzers
• wenn ein Button geklickt wird, wird eine bestimmte Methode ausgeführt
halloButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { Window.alert("Hallo"); }}
anonyme innere Klassekann aber auch ausgelagert werden
WORUM ES ABER EIGENTLICH GEHT:
REMOTE PROCEDURE CALLS
• Mechanismus um aus einem Browser heraus mit einem Server zu kommunizieren
• GWT stellt Hilfsklassen und Interfaces zur Verfügung
• serverseitig läuft ein Java-Servlet
• GWT verbirgt die Komplexität und übernimmt die Serialisierung
REMOTE PROCEDURE CALLS
Anf
rage
Ant
wor
t
Server
Client(Browser)G
oogl
e W
eb To
olki
t
Java-Servlet
JavaScript
nochmals zur Veranschaulichung...
BAUPLAN EINES REMOTESERVICES
Ein Service benötigt drei Komponenten:
1. clientseitige Java-Schnittstelle(Definition der Servicespezifikation)
2. serverseitige Implementierung des Services(die eigentlichen Methoden)
3. Schnittstelle für asynchrone Kommunikation(Der „Kleber“ zwischen Client und Server)
BAUPLAN EINES REMOTESERVICES
public interface MeinService extends RemoteService { String sagHallo(String deinName) throws IllegalArgumentException;}
• Erweitert die Schnittstelle RemoteService
• Definition der Servicespezifikation
clientseitige Java-Schnittstelle
BAUPLAN EINES REMOTESERVICES
• Teil des Java-Servlet
• Hier findet auch die Serialisierung statt (durch HTTPServlet)
serverseitige Implementierung des Services
public class MeinServiceImpl extends RemoteServiceServlet implements RechnenService { public sagHallo(String deinName) throws IllegalArgumentException { return "Hallo " + deinName; }}
BAUPLAN EINES REMOTESERVICES
• Ergänzung des Callback-Parameters
• AsyncCallback stellt die Methoden onSuccess und onFailure bereit
Schnittstelle für asynchrone Kommunikation
public interface MeinServiceAsync { void sagHallo(String deinName, AsyncCallback<String> callback) throws IllegalArgumentException;}
EIN BESPIEL-PROGRAMM
EIN BEISPIEL-PROGRAMM
<!doctype html><html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link type="text/css" rel="stylesheet" href="Referat.css"> <title>Kleine Server-Anfrage</title> <script type="text/javascript" language="javascript" src="referat/referat.nocache.js"></script> </head> <body>
<h1>Kleine Server Anfrage</h1>
<div id="inputPanel"> </div> </body></html>
Die Html-Host-Datei
EIN BEISPIEL-PROGRAMM
<!doctype html><html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link type="text/css" rel="stylesheet" href="Referat.css"> <title>Kleine Server-Anfrage</title> <script type="text/javascript" language="javascript" src="referat/referat.nocache.js"></script> </head> <body>
<h1>Kleine Server Anfrage</h1>
<div id="inputPanel"> </div> </body></html>
Die Html-Host-Datei
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint { private final RechnenServiceAsync rechnenService = GWT.create(RechnenService.class); public void onModuleLoad() { final Label plusZeichen = new Label(" + "); final TextBox summandEins = new TextBox(); final TextBox summandZwei = new TextBox(); final Button sendenButton = new Button("Vom Server ausrechnen lassen"); summandEins.setText("1"); summandZwei.setText("2"); RootPanel.get("inputPanel").add(summandEins); RootPanel.get("inputPanel").add(plusZeichen); RootPanel.get("inputPanel").add(summandZwei); RootPanel.get("inputPanel").add(sendenButton); /* ... */ }}
Die Clientseite
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint { private final RechnenServiceAsync rechnenService = GWT.create(RechnenService.class); public void onModuleLoad() { final Label plusZeichen = new Label(" + "); final TextBox summandEins = new TextBox(); final TextBox summandZwei = new TextBox(); final Button sendenButton = new Button("Vom Server ausrechnen lassen"); summandEins.setText("1"); summandZwei.setText("2"); RootPanel.get("inputPanel").add(summandEins); RootPanel.get("inputPanel").add(plusZeichen); RootPanel.get("inputPanel").add(summandZwei); RootPanel.get("inputPanel").add(sendenButton); /* ... */ }}
Die Clientseite
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint { private final RechnenServiceAsync rechnenService = GWT.create(RechnenService.class); public void onModuleLoad() { final Label plusZeichen = new Label(" + "); final TextBox summandEins = new TextBox(); final TextBox summandZwei = new TextBox(); final Button sendenButton = new Button("Vom Server ausrechnen lassen"); summandEins.setText("1"); summandZwei.setText("2"); RootPanel.get("inputPanel").add(summandEins); RootPanel.get("inputPanel").add(plusZeichen); RootPanel.get("inputPanel").add(summandZwei); RootPanel.get("inputPanel").add(sendenButton); /* ... */ }}
Die Clientseite
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint { private final RechnenServiceAsync rechnenService = GWT.create(RechnenService.class); public void onModuleLoad() { final Label plusZeichen = new Label(" + "); final TextBox summandEins = new TextBox(); final TextBox summandZwei = new TextBox(); final Button sendenButton = new Button("Vom Server ausrechnen lassen"); summandEins.setText("1"); summandZwei.setText("2"); RootPanel.get("inputPanel").add(summandEins); RootPanel.get("inputPanel").add(plusZeichen); RootPanel.get("inputPanel").add(summandZwei); RootPanel.get("inputPanel").add(sendenButton); /* ... */ }}
Die Clientseite
EIN BEISPIEL-PROGRAMM
EIN BEISPIEL-PROGRAMM
/* ... */
public interface RechnenService extends RemoteService { public String rechne(Integer summandEins, Integer summandZwei) throws IllegalArgumentException;}
Die Serviceschnittstelle
EIN BEISPIEL-PROGRAMM
/* ... */
public interface RechnenServiceAsync { void rechne(Integer summandEins, Integer summandZwei, AsyncCallback<String> callback)
throws IllegalArgumentException;}
Die asynchrone Schnittstelle
EIN BEISPIEL-PROGRAMM
/* ... */
public class RechnenServiceImpl extends RemoteServiceServlet implements RechnenService {
public String rechne(Integer summandEins, Integer summandZwei) throws IllegalArgumentException { Integer ergebnis = summandEins + summandZwei; return ergebnis.toString(); }
}
Das Servlet
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint {
/* ... */
sendenButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { Integer summandEinsInt = Integer.parseInt(summandEins.getText()); Integer summandZweiInt = Integer.parseInt(summandZwei.getText()); rechnenService.rechne(summandEinsInt, summandZweiInt, new AsyncCallback<String>() { public void onFailure(Throwable caught) { Window.alert("Der Server konnte nicht antworten"); } public void onSuccess(String result) { Window.alert("Antwort vom Server: " + result); } }); } }); }}
Die Clientseite - der Listener
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint {
/* ... */
sendenButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { Integer summandEinsInt = Integer.parseInt(summandEins.getText()); Integer summandZweiInt = Integer.parseInt(summandZwei.getText()); rechnenService.rechne(summandEinsInt, summandZweiInt, new AsyncCallback<String>() { public void onFailure(Throwable caught) { Window.alert("Der Server konnte nicht antworten"); } public void onSuccess(String result) { Window.alert("Antwort vom Server: " + result); } }); } }); }}
Die Clientseite - der Listener
EIN BEISPIEL-PROGRAMM
/* ... */
public class Referat implements EntryPoint {
/* ... */
sendenButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { Integer summandEinsInt = Integer.parseInt(summandEins.getText()); Integer summandZweiInt = Integer.parseInt(summandZwei.getText()); rechnenService.rechne(summandEinsInt, summandZweiInt, new AsyncCallback<String>() { public void onFailure(Throwable caught) { Window.alert("Der Server konnte nicht antworten"); } public void onSuccess(String result) { Window.alert("Antwort vom Server: " + result); } }); } }); }}
Die Clientseite - der Listener
EIN BEISPIEL-PROGRAMM
FRAGEN?