1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Jetty Webserver in einem Javaprogramm

Grundzüge von einem embedded Webserver

  1. melmager
    Ich gehe hier der Frage nach wie übertrage ich Daten von
    Android nach einem PC/Server
    Teil eins: Der Webserver in der Java anwendung

    http://www.eclipse.org/jetty/
    https://webtide.com/downloads/

    http://www.eclipse.org/jetty/documentation/current/advanced-embedding.html

    Download:
    https://repo1.maven.org/maven2/org/...v20160915/jetty-all-9.3.12.v20160915-uber.jar

    Embedded Webserver Jetty für Java

    Alles fing mit der Frage an: "Wie übertrage ich Daten von Android zum Server"

    Mit der Suche im Web bin ich auf diverse Begriffe gestossen wie "REST", "SOAP"

    alle diese Techniken benötigen allerdings auf der Serverseite viel Aufwand
    und folgen der Idee "Server startet Anwendung". Und alle diese Techniken basieren auf
    Html / Web Übertragungs techniken.

    Ich wollte aber was "kleines" was in Java eingebunden werden kann, also ein Server in der Java Anwendung.

    Auf der Server / PC Seite bin ich bei meiner Suche auf embedded Jetty gestossen, einem Webserver der in einem Javaprogramm
    eingebunden werden kann.

    Siehe auch http://www.eclipse.org/jetty/documentation/current/advanced-embedding.html

    "embedded" ist in dem zusammenhang wichtig, da es den Jetty auch als vollwertigen Http Server gibt der dem klassischen .
    Aufbau folgt "Webserver startet Anwendung".

    Schauen wir erst mal auf die Übertragungsmöglichkeiten beim Webserver.
    Daten zum Server : dort gibt es POST, GET, und Fileupload.
    GET ist die Technik wo die Informationen an die URL "dranhängen"
    POST ist die bessere Wahl, da die Daten im Header mit übergeben werden und diese Version wird hier im Tutorial eingesetzt.

    Bei POST arbeitet man mit Key und Value, man überträgt ein Variablennamen
    und den Inhalt dazu.
    Daten zum Client Transport ist einfach Text in Form von XML / Html oder auch Filedownload.

    Kommen wir zum Jettyserver. Der Server arbeitet Ereignisgesteuert wobei das Ereignis
    das aufrufen einer URL ist. Sobald der Server aufgerufen wird ruft der seinerseits ein
    Handler oder ein Servlet auf. Da es hier um möglichst einfach geht behandle ich hier
    die Handler Technik.

    Der Jettyserver ruft genau einen Handler auf. Das ist langweilig :) Aber die Einschränkung bekommen wir auch noch
    geregelt.

    Starten wir einfach mit einem AbstractHandler einer der Grundklasse für Handler.

    Unter dem Strich geht es darum eine Classe zu schreiben die den AbstractHandler erweitert
    um vom Client übertragenden Postdaten zu verarbeiten.

    Fangen wir mit der simplen Variante an:

    Code (Text):
    1. import org.eclipse.jetty.server.Server;
    2. import org.eclipse.jetty.server.handler.ContextHandler;
    3. import org.eclipse.jetty.server.handler.HandlerList;
    4. import org.eclipse.jetty.server.handler.ResourceHandler;
    5.  
    6. public class TutorialServer {
    7.  
    8.     /**
    9.      * @param args the command line arguments
    10.      */
    11.     public static void main(String[] args) {
    12.         System.out.println("start");
    13.    
    14.         // erzeugen des Jetty Servers auf port 8080
    15.         Server server = new Server(8080);
    16.         // setup Handler - hier wird noch erweitert
    17.    
    18.         //der Jettyserver bekommt unseren erweiterten Handler
    19.         server.setHandler(new MyTestHandler());
    20.    
    21.    
    22.         // und start Server
    23.         try {
    24.             server.start();
    25.             server.join();
    26.         } catch (Exception ex) {
    27.             ex.printStackTrace();
    28.         }
    29.     }
    30. }
    Das war schon der Server.
    Kommen wir zu unserem Handler - dazu muss die Classe den AbstractHandler erweitern.
    Unser Handler sendet ein Eingabeformular und druckt die vom Formular gesendeten Postvariablen Name/Inhalt aus.

    Code (Text):
    1. import javax.servlet.ServletException;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4.  
    5. import org.eclipse.jetty.server.Request;
    6. import org.eclipse.jetty.server.handler.AbstractHandler;
    7.  
    8.  
    9. public class MyTestHandler extends AbstractHandler {
    10.  
    11.     @Override
    12.     public void handle(String string, Request baserequest, HttpServletRequest hsr, HttpServletResponse response) throws IOException, ServletException {
    13.         // response encoding and types
    14.         response.setContentType("text/html; charset=utf-8");
    15.  
    16.         // response status code - sende alles ok an Client
    17.         response.setStatus(HttpServletResponse.SC_OK);
    18.  
    19.         System.out.println("method :" + hsr.getMethod());  //welche methode - POST oder GET
    20.         System.out.println("pathinfo " + hsr.getPathInfo()); //verzeichnis Pfad abzüglich Context
    21.         System.out.println("context " + hsr.getContextPath()); // in welchen Context bewegen wir uns
    22.    
    23.         // POST Variablen namen ausgeben
    24.    
    25.         Enumeration<String> list = hsr.getParameterNames();
    26.         while (list.hasMoreElements()) {
    27.             String postname = list.nextElement(); //variablenname
    28.             String postvalue = hsr.getParameter(postname); //inhalt der Variable
    29.             System.out.println("var " + postname + " value " + postvalue); //ausgabe auf Console
    30.         }
    31.  
    32.         // Write response: hier ein kleines Eingabeformular für den Client für den Anfang
    33.         response.getWriter().println("<h1>Hello World</h1><form action=\"/test/return.html\" method=\"post\" > ");
    34.         response.getWriter().println("<input type=\"text\" name=\"return\" /> ");
    35.         response.getWriter().println("</form>");
    36.  
    37.         // Sage dem Server das die Anfrage abgearbeitet wurde - sprich wenn weitere Handler noch in der Liste sind
    38.         // die werden nicht mehr gebraucht
    39.         baserequest.setHandled(true);
    40.  
    41.     }
    42.  
    43. }
    Bei dem Aufbau des Eingabeformulars ist das \ Zeichen ein Maskierungszeichen für die " Zeichen.
    aus \" wird nach dem Compilerdurchlauf ".

    Kommen wir zu der Technik das mehrere Handler abgearbeitet werden können.

    Um das zu erreichen setzt man eine HandlerList ein. Das ist ein Handler der alle Handler aufruft die in seiner
    interne Liste sind.

    Code (Text):
    1. HandlerList handlerlist = new HandlerList();
    2. handlerlist.addHandler(cont);
    mit addHandler wird ein Handler zur Liste hinzugefügt.


    Als nächstes benötigen wir ein Filter. Das wird mittels eines ContextHandler gemacht.

    Ein Context ist ein Teil der URL die vom Client aufgerufen wird.
    Wir haben folgenden URL Aufbau:
    //my.webserver.de/context_teil/datei.html

    Ein ContexHandler arbeitet als Filter, da er nur Anfragen vom Client an den nächsten Handler weiterleitet
    die dem Context entsprechen.

    Wenn wir die main classe erweitern:

    Code (Text):
    1.    // erzeugen des Jetty Servers auf port 8080
    2.    Server server = new Server(8080);
    3.    // main wird erweitert
    4.  
    5.    // erzeugen der Handlerliste
    6.    HandlerList handlerlist = new HandlerList();
    7.  
    8.    // erzeuge Filter mit dem context /test
    9.    ContextHandler cont = new ContextHandler("/test");
    10.    // filter ruft erneut unser eigenen Handler auf
    11.    cont.setHandler(new MyTestHandler());
    12.    // filer auf die Liste  
    13.    handlerlist.addHandler(cont);
    14.    // server erhält die liste    
    15.    server.setHandler(handlerlist);
    16.    // starte Server siehe oben
    Kommen wir zum folgenden Aufbau: (> steht für ruft auf)

    JettyServer > HandlerList (ruft alle Handler in der Liste auf) > ContexHandler (Filter) > eigene Classe (AbstractHandler)


    Hier im Tutorial gehe ich davon aus das unser Server die IP 192.168.1.50 hat, bei eigenen Versuchen bitte entsprechend anpassen.

    Wenn wir nun das Programm starten und mit dem Browser "//192.168.1.50:8080/test aufrufen" kommt ein nettes Hallo und ein
    Einabeformular. Das ruft beim absenden erneut die Seite auf und unser Server sollte die Post Variablename "return" ausgeben
    und das was wir im Browser eingegeben haben.
    Allerdings bekommen wir vom Server nur dann eine Antwort wenn wir den context (verzeichnis) /test nutzen.

    lernen wir den ResourceHandler kennen.
    dem Handler können wir ein Verzeichnis auf dem Server mitgeben und dort sollte eine Webseite sein.
    Die Webseite muss allerdings Statisch sein, also Html Dateien pur - auch mit Unterverzeichnissen, Links gehen natürlich :)
    So einfach kann ein Webserver sein.

    Code (Text):
    1. // weiterer Handler für die Main Classe
    2.  
    3.         ResourceHandler resource_handler = new ResourceHandler();
    4.         resource_handler.setDirectoriesListed(true);
    5.         resource_handler.setWelcomeFiles(new String[]{"index.html"});
    6.         //das locale verzeichnis auf dem Rechner setzen - muss euren gegebenheiten angepasst werden !
    7.         resource_handler.setResourceBase("/home/susi/homepage/www.net-wolf.de"); //das locale verzeichnis auf dem Rechner
    8.  
    9.         ContextHandler chtm = new ContextHandler("/html");
    10.         chtm.setHandler(resource_handler);
    11.         // der neue Handler auf die Liste
    12.         handlerlist.addHandler(chtm);
    13.    
    jetzt haben wir 2 Urls die wir aufrufen können.
    //192.168.1.50:8080/test ist weiter unser Eingabeformular
    //192.168.1.50:8080/html ist die statische Webseite