Skip to content

4. Ausführen der Anwendung

Wir möchten die Anwendung nun außerhalb der STS-IDE (für den Server) und von WebStorm (für den Client) ausführen.

4.1. Bereitstellung des Webdienstes auf einem Tomcat-Server

In Abschnitt 2.11.9 haben wir gesehen, wie man ein WAR-Archiv für Tomcat erstellt. Wir wiederholen den Vorgang hier. Um die bestehende Struktur beizubehalten, duplizieren wir zunächst das Eclipse-Projekt [rdvmedecins-webapi-v3] in [rdvmedecins-webapi-v4].

  

Die Datei [pom.xml] wird wie folgt geändert:


    <modelVersion>4.0.0</modelVersion>
    <groupId>istia.st.spring4.mvc</groupId>
    <artifactId>rdvmedecins-webapi-v4</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
 
    <name>rdvmedecins-webapi-v3</name>
    <description>Gestion de RV Médecins</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.0.0.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>istia.st.spring4.rdvmedecins</groupId>
            <artifactId>rdvmedecins-metier-dao-v2</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
</dependencies>

Änderungen müssen an zwei Stellen vorgenommen werden:

  • Zeile 5: Sie müssen angeben, dass Sie eine WAR-Datei (Web ARchive) generieren möchten;
  • Zeilen 23–27: Sie müssen eine Abhängigkeit zum Artefakt [spring-boot-starter-tomcat] hinzufügen. Dieses Artefakt enthält alle Tomcat-Klassen in den Abhängigkeiten des Projekts;
  • Zeile 26: Dieses Artefakt ist [provided], was bedeutet, dass die entsprechenden Dateien nicht in die generierte WAR-Datei aufgenommen werden. Stattdessen befinden sich diese Dateien auf dem Tomcat-Server, auf dem die Anwendung ausgeführt wird;

Sie müssen außerdem die Webanwendung konfigurieren. Wenn keine [web.xml]-Datei vorhanden ist, erfolgt dies über eine Klasse, die [SpringBootServletInitializer] erweitert:

  

Die Klasse [ApplicationInitializer] sieht wie folgt aus:


package rdvmedecins.web.config;
 
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
 
public class ApplicationInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(AppConfig.class);
    }
 
}
  • Zeile 6: Die Klasse [ApplicationInitializer] erweitert die Klasse [SpringBootServletInitializer];
  • Zeile 8: Die Methode [configure] wird überschrieben (Zeile 7);
  • Zeile 9: Die Klasse [AppConfig] dient zur Konfiguration des Projekts;

Sobald dies erledigt ist, müssen Sie möglicherweise das Maven-Projekt aktualisieren (ich musste dies tun): [Rechtsklick auf das Projekt / Maven / Projekt aktualisieren] oder [Alt-F5].

Um das Projekt auszuführen, gehen Sie wie folgt vor:

  • Führen Sie in [1] das Projekt auf einem der in der Eclipse-IDE registrierten Server aus;
  • Wählen Sie in [2] die Option [tc Server Developer] aus, die als Standardoption voreingestellt ist. Dabei handelt es sich um eine Variante von Tomcat;

Sie erhalten das folgende Ergebnis:

 

Das ist normal. Denken Sie daran, dass der Webdienst die URL [/] nicht in seinen Methoden enthält. Wenn Sie die URL [/getAllMedecins] aufrufen, erhalten Sie folgende Antwort:

 

Das ist normal. Der Webdienst ist geschützt.

Starten wir nun den Client [rdvmedecins-angular-v2] in WebStorm:

Geben Sie unter [1] die URL des neuen Webdienstes [http://localhost:8080/rdvmedecins-webapi-v4] ein. Wir erhalten folgendes Ergebnis:

Image

Um die Anwendung außerhalb der STS-IDE auszuführen, gibt es verschiedene Lösungen. Hier ist eine davon.

Laden Sie eine Version von Tomcat [http://tomcat.apache.org/download-80.cgi] (Juli 2014) herunter:

Wählen Sie unter [1] eine komprimierte Version aus und entpacken Sie diese unter [2]. Kehren Sie zu STS zurück:

  • Klicken Sie auf der Registerkarte [Server] mit der rechten Maustaste auf die Anwendung [rdvmedecins-webapi-v4] und wählen Sie die Option [Bereitstellungsort durchsuchen];
  • in [4]: Kopieren Sie den Ordner [rdvmedecins-webapi-v4];
  • Fügen Sie in [5] den Ordner [rdvmedecins-webapi-v4] in den Tomcat-Ordner [webapps] ein;
  • Führen Sie in [6] die Befehlsdatei [startup.bat] aus (der in STS integrierte Tomcat-Server muss angehalten sein). Es öffnet sich ein DOS-Fenster, in dem die Tomcat-Protokolle angezeigt werden. Diese sollten zeigen, dass die Anwendung [rdvmedecins-webapi-v4] gestartet wurde.

Um dies zu überprüfen, führen Sie den Angular-Client [rdvmedecins-angular-v2] erneut in WebStorm aus:

Geben Sie in [1] die URL des neuen Webdienstes [http://localhost:8080/rdvmedecins-webapi-v4] ein. Sie sehen das folgende Ergebnis:

Image

4.2. Bereitstellung des Angular-Clients auf dem Tomcat-Server

Nachdem der Webdienst nun auf Tomcat bereitgestellt wurde, werden wir nun auch den Angular-Client auf einem Server bereitstellen. Dies könnte durchaus der Server sein, auf dem der Webdienst bereits gehostet wird. Wir werden diesen Ansatz wählen.

Zunächst duplizieren wir den Client [rdvmedecins-angular-v2] als [rdvmedecins-angular-v3] und nehmen die folgenden Änderungen vor:

  • In [1] wurde alles in einen Ordner namens [ app] verschoben;
  • in [1] haben wir den Ordner [bower-components] entfernt, der die verschiedenen für das Projekt erforderlichen CSS- und JS-Bibliotheken enthielt. Alle diese Elemente wurden in den Ordner [lib] kopiert [2];
  • in [1] wurde die Datei [app.html] in [index.html] umbenannt;

Die Datei [index.html] wurde angepasst, um den geänderten Pfaden der verwendeten Ressourcen Rechnung zu tragen:


<!DOCTYPE html>
<html ng-app="rdvmedecins">
<head>
  <title>RdvMedecins</title>
...
  <!-- on CSS -->
  ...
  <link href="lib/bootstrap-theme.min.css" rel="stylesheet"/>
  <link href="lib/bootstrap-select.min.css" rel="stylesheet"/>
</head>
<!-- controller [appCtrl], model [app] -->
<body ng-controller="appCtrl">
<div class="container">
  ...
</div>
<!-- Bootstrap core JavaScript ================================================== -->
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/bootstrap-select.min.js"></script>
<script type="text/javascript" src="lib/footable.js"></script>
<!-- angular js -->
<script type="text/javascript" src="lib/angular.min.js"></script>
<script type="text/javascript" src="lib/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="lib/angular-route.min.js"></script>
<script type="text/javascript" src="lib/angular-translate.min.js"></script>
<script type="text/javascript" src="lib/angular-base64.min.js"></script>
<!-- modules -->
...
<!-- services -->
...
<!-- guidelines -->
...
<!-- controllers -->
....
</body>
</html>

Außerdem wurde der [loginCtrl]-Controller so angepasst, dass er auf den richtigen Server verweist, sodass der Benutzer die URL nicht eingeben muss:


// credentials
app.serverUrl = "http://localhost:8080/rdvmedecins-webapi-v4";
app.username = "admin";
app.password = "admin";

Nachdem dies erledigt ist, führen wir nun die Datei [index.html] aus:

Anschließend melden wir uns beim Webdienst an. Es sollte funktionieren. Sobald dies überprüft ist, stoppen wir den Tomcat-Server. Wir werden den integrierten STS-Server wiederverwenden.

Kopieren Sie in STS den gesamten Inhalt des Ordners [rdvmedecins-angular-v3/app] in den Ordner [webapp] des Projekts [rdvmedecins-webapi-v4] (Registerkarte „Navigator“) [1]:

Starten Sie anschließend [2] den STS-VMware-Server und rufen Sie die URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html] auf:

Unter [3] tritt ein Berechtigungsproblem auf. Das ist nicht überraschend, da wir den Webdienst gesichert haben. Wir müssen festlegen, dass der Zugriff auf die Datei [/app/index.html] uneingeschränkt ist. Kehren wir zu Eclipse zurück:

  

Denken Sie daran, dass die Zugriffsberechtigungen in der Klasse [SecurityConfig] definiert wurden. Ändern wir diese wie folgt:


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // CSRF
        http.csrf().disable();
        // the password is transmitted by the header Authorization: Basic xxxx
        http.httpBasic();
        // the HTTP OPTIONS method must be authorized for all
        http.authorizeRequests() //
                .antMatchers(HttpMethod.OPTIONS, "/", "/**").permitAll();
        // the [app] folder is accessible to all
        http.authorizeRequests() //
                .antMatchers(HttpMethod.GET, "/app", "/app/**").permitAll();
        // only the ADMIN role can use the application
        http.authorizeRequests() //
                .antMatchers("/", "/**") // all URL
                .hasRole("ADMIN");
}
  • Zeilen 11–12: Wir gewähren allen Benutzern die Berechtigung, den Ordner [app] und dessen Inhalt zu lesen. Dazu folgen wir dem Beispiel der vorherigen Zeilen.

Starten Sie nun den STS-Tomcat-Server neu und rufen Sie die URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html] erneut auf:

Image

Diesmal funktioniert es.

4.3. CORS-Header

Sie erinnern sich vielleicht, dass wir uns mit der Handhabung von CORS-Headern ziemlich schwergetan haben. Im vorherigen Beispiel:

  • befindet sich der Webdienst unter der URL [http://localhost:8080/rdvmedecins-webapi-v4];
  • befindet sich der HTML-Client unter der URL [http://localhost:8080/rdvmedecins-webapi-v4/app];

Der HTML-Client und der Webdienst befinden sich also auf demselben Server [http://localhost:8080]. Es gibt keine CORS-Konflikte, da diese nur auftreten, wenn sich Client und Server nicht in derselben Domäne befinden. Das sollten wir überprüfen können. Kehren wir zu STS zurück:

  

Ob CORS-Header generiert werden oder nicht, wird durch einen in der Klasse [ApplicationModel] definierten booleschen Wert gesteuert:


    // données de configuration
    private boolean CORSneeded = true;

Wir setzen den obigen booleschen Wert auf false, starten den Webdienst neu und rufen die URL [http://localhost:8080/rdvmedecins-webapi-v4/app/index.html] erneut auf. Wir können sehen, dass die Anwendung funktioniert.

4.4. Bereitstellung des Angular-Clients auf einem Android-Tablet

Mit dem [Phonegap]-Tool [http://phonegap.com/] können Sie aus einer HTML/JS/CSS-Anwendung eine ausführbare Datei für Mobilgeräte (Android, iOS, Windows 8 usw.) generieren. Dafür gibt es verschiedene Möglichkeiten. Wir verwenden die einfachste: ein Online-Tool, das auf der Phonegap-Website [http://build.phonegap.com/apps] verfügbar ist.

  • Bevor Sie mit [1] beginnen, müssen Sie möglicherweise ein Konto erstellen;
  • Beginnen Sie in [1];
  • Wählen Sie unter [2] einen kostenlosen Tarif, der nur eine Phonegap-App zulässt;
  • Laden Sie in [3] die komprimierte Anwendung [4] herunter (der in Abschnitt 4.2 erstellte Ordner [app] ist komprimiert);
  • Geben Sie in [5] der App einen Namen;
  • Erstellen Sie die App in [6]. Dies kann etwa 1 Minute dauern. Warten Sie, bis die Symbole für die verschiedenen mobilen Plattformen anzeigen, dass der Build abgeschlossen ist;
  • Es wurden nur die Binärdateien für Android [7] und Windows [8] generiert;
  • klicken Sie auf [7], um die Android-Binärdatei herunterzuladen;
  • in [9] die heruntergeladene [apk]-Binärdatei;

Starten Sie einen [GenyMotion]-Emulator für ein Android-Tablet (siehe Abschnitt 6.4):

 

Oben starten wir einen Tablet-Emulator mit Android API 16. Sobald der Emulator gestartet ist,

  • entsperren Sie ihn, indem Sie das Schloss (falls vorhanden) zur Seite ziehen und dann loslassen;
  • Ziehen Sie die heruntergeladene Datei [PGBuildApp-debug.apk] mit der Maus auf den Emulator und legen Sie sie dort ab. Sie wird dann installiert und ausgeführt;

Sie müssen die URL in [1] ändern. Geben Sie dazu in einem Eingabeaufforderungsfenster den Befehl [ipconfig] (Zeile 1 unten) ein, wodurch die verschiedenen IP-Adressen Ihres Computers angezeigt werden:


C:\Users\Serge Tahé>ipconfig
 
Configuration IP de Windows
 
 
Carte réseau sans fil Connexion au réseau local* 15 :
 
   Statut du média. . . . . . . . . . . . : Média déconnecté
   Suffixe DNS propre à la connexion. . . :
 
Carte Ethernet Connexion au réseau local :
 
   Suffixe DNS propre à la connexion. . . : ad.univ-angers.fr
   Adresse IPv6 de liaison locale. . . . .: fe80::698b:455a:925:6b13%4
   Adresse IPv4. . . . . . . . . . . . . .: 172.19.81.34
   Masque de sous-réseau. . . . . . . . . : 255.255.0.0
   Passerelle par défaut. . . . . . . . . : 172.19.0.254
 
Carte réseau sans fil Wi-Fi :
 
   Statut du média. . . . . . . . . . . . : Média déconnecté
   Suffixe DNS propre à la connexion. . . :
 
...

Notieren Sie sich entweder die WLAN-IP-Adresse (Zeilen 6–9) oder die IP-Adresse des lokalen Netzwerks (Zeilen 11–17). Verwenden Sie diese IP-Adresse dann in der URL des Webservers:

 

Sobald dies erledigt ist, stellen Sie eine Verbindung zum Webdienst her:

Testen Sie die Anwendung auf dem Emulator. Sie sollte funktionieren. Auf der Serverseite können Sie CORS-Header in der Klasse [ApplicationModel] zulassen oder auch nicht:


    // données de configuration
    private boolean CORSneeded = false;

Dies ist für die Android-App irrelevant. Sie läuft nicht in einem Browser. Die Anforderung des CORS-Headers stammt vom Browser, nicht vom Server.

4.5. Bereitstellung des Angular-Clients auf einem Android-Smartphone-Emulator

Wir wiederholen den vorherigen Schritt mit einem Smartphone-Emulator. Wir wollen überprüfen, wie sich unser Client auf kleinen Bildschirmen verhält:

  • In [1] starten wir einen Smartphone-Emulator;
  • in [2] und [3] wurde die Navigationsleiste zu einem Menü zusammengeklappt;
  • in [4] melden wir uns an;
  • in [5] werden die Liste und der Kalender übereinander statt nebeneinander angezeigt;
  • in [6] rufen wir den Kalender auf;
  • in [7] ist ein Teil der Zeitfenster ausgeblendet, da der Bildschirm zu klein ist. Die [footable]-Bibliothek hat dies übernommen;
  • in [8] die gleiche Ansicht wie zuvor, diesmal jedoch mit einem Termin.

Insgesamt passt sich unsere App recht gut an das Smartphone an. Es könnte sicherlich besser sein, aber sie bleibt dennoch benutzerfreundlich.