FAQ: Webservices erstellen und bereitstellen

Wie installiere ich einen Tomcat-Server? Auf Servern im Internet läuft der Tomcat-Application-Server meistens auf einem Linux Betriebssystem. Eine Beschreibung, wie Tomcat unter Linux installiert werden kann, kann der Beschreibung einer Tomcat-Installation auf einem Raspberry-Pi entnommen werden. Unter Windows kann Tomcat "eigentlich" einfach durch die Installation von XAMPP installiert werden. Das hat den Vorteil, dass gleich ein Apache-HTTP-Server und eine MySQL-Datenbank mit installiert werden (beide werden für einfache Webservices aber nicht benötigt, Tomcat reicht). Leider ist dei mit XAMMP ausgelieferte Tomcat-Version meistens mindestens 2 Versionen überaltert. Deshalb ist es sinnvoll, manuell eine aktuelle Tomcat-Version zu installieren. Aktuelle Tomcat-Version von http://tomcat.apache.org/ herunterladen. Einen Ordner tomcat z.B. auf Laufwerk C: anlegen (man kann Tomcat natürlich auch an einem anderen Ort installieren). Im Ordner tomcat die heruntergeladene Installationsdatei entpacken. Dann die Datei tomcat-users.xml im Ordner conf editieren und dort z.B. Folgendes einfügen: <user username="max" password="geheim" roles="admin-gui,manager-gui,manager-status,manager-script"/> Eventuell sind weitere Rechte nötig (Tomcat-Dokumentation gibt Hinweise). Der Tomcat-Server kann nun über die startup.bat im bin-Verzeichnis von Tomcat gestartet werden. Testen, ob Tomcat wirklich läuft, ist über localhost:8080 möglich. Falls Tomcat noch nicht läuft, wurde die Umgebungsvariable JAVA_HOME eventuell nicht gesetzt.

Wie erstelle ich einen Java-Webservice? Die folgende Beschreibung geht davon aus, dass ein Java-Development-Kit (JDK), die Entwicklungsumgebung NetBeans und der Application-Server Tomcat in einer möglichst aktuellen Version unter Microsoft-Windows installiert sind.

  Als Beispiel erstellen wir hier einen sehr einfachen Webservice, der zwei Zahlen addieren kann.

  Dazu legen wir in NetBeans ein neues Projekt wie folgt an:

  1. File / New Project
  2. Unter Categories "Java Web" und "Web Application" wählen
  3. Dann "Next" anklicken
  4. Project Name: Rechner
  5. Dann "Next" anklicken
  6. Server: Apache Tomcat or TomEE
  7. Context Path: Rechner
  8. Dann "Next" anklicken
  9. Dann "Finish" anklicken

  F6 oder Klick auf den grünen Startpfeil startet die Java Web Applikation im Browser (es wird
  der Standardbrowser des Systems gestartet) unter der URL http://localhost:8080/Rechner

  Die gestartete Java Web Applikation zeigt erst einmal nur den Inhalt "TODO write content" einer
  index.html Datei an, die bei Erstellen des Projektes automatisch erzeugt wurde. Diese Datei eignet
  sich gut, um das Projekt zu dokumentieren.

  Wir legen nun unseren Addierer-Webservice in unserem Rechner an (später können wir weitere
  Services ergänzen, z.B. einen Multiplizierer-Webservice):

  1. Rechtsklick auf den Folder "Source Packages"
  2. New / Java Package
  3. Package Name: rechner
  4. Dann "Finish" anklicken
  5. Rechtsklick auf den den neuen Folder "rechner"
  6. New / Servlet
  7. Class Name: Addierer
  8. Dann "Next" anklicken
  9. Dann "Finish" anklicken

  F6 oder Klick auf den grünen Startpfeil startet die Java Web Applikation erneut
  unter der URL http://localhost:8080/Rechner

  Wir ergänzen die URL zu: http://localhost:8080/Rechner/Addierer

  Im Browser wird nun der Inhalt "Servlet Addierer at /Rechner" angezeigt, der von unserem
  Addierer-Servlet generiert wurde. Die Ausgabe findet in der folgenden Methode statt:

  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {
      /* TODO output your page here. You may use following sample code. */
      out.println("<!DOCTYPE html>");
      out.println("<html>");
      out.println("<head>");
      out.println("<title>Servlet Addierer</title>");
      out.println("</head>");
      out.println("<body>");
      out.println("<h1>Servlet Addierer at " + request.getContextPath() + "</h1>");
      out.println("</body>");
      out.println("</html>");
    }
  }


Das Objekt request repräsentiert die Anfrage an das Addierer-Servlet, und über
das Objekt response kann die Antwort zurückgeliefert werden.

Unser Addierer soll zwei Zahlen mit den Namen zahl1 und zahl2 entgegen nehmen.
Beide Zahlen addiert werden. Das Ergebnis soll im HTML-Format zurückgeliefert
werden.

Wir ändern den Code wie folgt ab, um die Addierer-Funktionalität zu implementieren:


  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {
            // Nimm zahl1 und zahl2 aus der Anfrage entgegen
            final String zahl1 = request.getParameter("zahl1");
            final String zahl2 = request.getParameter("zahl2");
            // Wandle beide Zahlen aus dem String-Format in Zahlen
            // mit Nachkommastellen um (hier sollte noch eine
            // Fehlerbehandlung implementiert werden, da zahl1
            // und/oder zahl2 ungültig oder leer sein können)
            final double z1 = Double.parseDouble(zahl1);
            final double z2 = Double.parseDouble(zahl2);
            // Addiere beide Zahlen
            final double summe = z1 + z2;
            // Gib das Ergebnis im Html-Format zurück
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Addierer</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>" + summe + "</h1>");
            out.println("</body>");
            out.println("</html>");
        }
  }

F6 oder Klick auf den grünen Startpfeil startet die Java Web Applikation erneut
unter der URL http://localhost:8080/Rechner

Wir ergänzen die URL zu: http://localhost:8080/Rechner/Addierer?zahl1=123&zahl2=456

Im Browser wird nun die Summe 579.0 angezeigt, die von unserem Addierer-Servlet aus den
übergebenen Zahlen 123 und 456 berechnet und dann an den Browser zurückgeliefert wurde.

Achtung: Es findet keine ordentliche Fehlerbehandlung in unserem Addierer-Webservice statt!
Da ist also noch was zu tun, das wird hier aber nicht weiter thematisiert.
  
Nun erstellen wir uns eine Html-Datei mit dem Namen "Addierer.html", die die Eingabe von
zwei Zahlen ermöglicht, diese Zahlen dann zum Webservice sendet und das Ergebnis anzeigt.

Das geht mit einem einfachen Editor wie Notepad++ oder Atom:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Addierer</title>
</head>

<body>
  <form action="http://localhost:8080/Rechner/Addierer">
    Zahl 1: <input type="number" name="zahl1" value="0">
    <br>
    Zahl 2: <input type="number" name="zahl2" value="0">
    <br><br>
    <input type="submit" value="Addieren">
  </form>
</body>

</html>


Wird die Datei "Addierer.html" mit einem Browser geöffnet, können dort 2 Zahlen
eingegeben werden. Nach Klick auf den Button "Addieren" werden die Zahlen zum
Webservice gesendet. Der Webservice nimmt die Zahlen als String unter ihren Namen
zahl1 und zahl2 entgegen, wandelt sie in Zahlen mit Nachkommstellen um, addiert
die Zahlen und liefert das Ergebnis im Html-Format an den Browser zurück. Der
Browser zeigt das Ergebnis dann an.
Der Addierer-Webservice liefert in der Variante, die wir weiter oben implementiert
haben, das Ergbebnis im HTML-Format zurück. Das scheint ganz praktisch zu sein,
der Browser nimmt das Ergebnis einfach entgegen und kann es direkt anzeigen.

Allerdings hat das auch Nachteile. Möchte man die Oberfläche von der Berechnung
trennen, damit jeder Client die Oberfläche (GUI) selbst so gestalten kann, wie er
das möchte, dann ist es praktischer, die Daten in einem Format wie XML oder JSON
auszuliefern. Ein Client nimmt dann die Daten entgegen und intergiert sie in die
eigene Weboberfläche.

Häufig ist es auch so, dass mehrere Webservices von einem Client genutzt werden.
Spätestens dann macht eine Auslieferung von Ergebnissen im HTML-Format keinen Sinn
mehr, denn wie sollten mehrere zurückgelieferte HTML-Ergebnisse auf einer einzigen
HTML-Seite angezeigt werden?

Viele Webservices bieten verschiedene Rückgabeformate an, der Client kann wählen,
welches Format er gerne hätte (gängig sind XML, JSON und HTML).

Wir wollen hier aber erst einmal keine Wahl von verschiedenen Formaten anbieten,
sondern stellen unser Ausgabeformat auf JSON um. Dazu ändern den Code wie folgt ab:


protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
  // Enable cross-origin resource sharing
  response.addHeader("Access-Control-Allow-Origin", "*");
  // Content-Type auf JSON setzen
  response.setContentType("application/json");
  try (PrintWriter out = response.getWriter()) {
    // Nimm zahl1 und zahl2 aus der Anfrage entgegen
    final String zahl1 = request.getParameter("zahl1");
    final String zahl2 = request.getParameter("zahl2");
    // Wandle beide Zahlen aus dem String-Format in Zahlen
    // mit Nachkommastellen um (hier sollte noch eine
    // Fehlerbehandlung implementiert werden, da zahl1
    // und/oder zahl2 ungültig oder leer sein können)
    final double z1 = Double.parseDouble(zahl1);
    final double z2 = Double.parseDouble(zahl2);
    // Addiere beide Zahlen
    final double summe = z1 + z2;
    // Gib das Ergebnis im JSON-Format zurück
    // JSON öffnende Klammer
    out.println("{");
    // Ergebnis (Summe)
    out.println("\"Summe\" : " + summe);
    // JSON schliessende Klammer
    out.println("}");
  }
}

F6 oder Klick auf den grünen Startpfeil startet die Java Web Applikation erneut
unter der URL http://localhost:8080/Rechner

Wir ergänzen die URL wieder zu:
http://localhost:8080/Rechner/Addierer?zahl1=123&zahl2=456

Im Browser wird die Summe 579.0 nun im JSON-Format angezeigt.

Wie Webservices genutzt werden können, die ihre Ergebnisse im JSON-Format
zurückliefern, wird unter FAQ: Webservices nutzen beschrieben. Oder schauen
Sie sich den folgenden Gehaltsrechner an, der einen Gehaltsrechner-Webservice
für die Berechnung der Gehaltswerte benutzt.

Nach Aufruf der folgenden Musterlösung können Sie wie gewohnt die Quelltexte (html, css und js) über
"rechte Maustaste + Seitenquelltext anzeigen" begutachten. Sie gelangen zuerst in den HTML-Quelltext
und finden dort auch die Verweise auf die eingebundenen CSS- und JavaScript Dateien, die Sie dort
nur anklicken müssen.
Gehaltsrechner für ein Personalbüro mit einer Nettowunsch-Funktion
Gehaltsrechner-Webservice, der in der Musterlösung genutzt wird

Wie kann ich meinen Webservice auf einem (fremden) Tomcat-Server bereitstellen? Während der Programmentwicklung kümmert sich die NetBeans-Entwicklungsumgebung darum, den Webservice über den Tomcat-Application-Server bereitzustellen. Möchte man den fertigen Service nun über ein anderen Application-Server verfügbar machen, so ist das recht einfach. Eine lauffähige Web-Applikation besteht aus einer Datei mit der Endung .war, die NetBeans im Unterordner dist des Projektes ablegt. Der Rechner-Webservice steckt beispielsweise in der Datei Rechner.war. Im Verzeichnisbaum eines Tomcat-Application-Servers gibt es einen Unterordner webapps. Dorthin können fertige Applikationen wie Rechner.war kopiert werden. Der Tomcat-Server startet diese dann automatisch und der Webservice steht bereit. Zum Löschen eines Webservices muss lediglich die entsprechende war-Datei aus dem Ordner webapps entfernt werden.