Zurück zum Manuskript
// Datei: TelefonbuchServer.java // Autor: Werner Brecht // Datum: 24.07.2018 // Thema: Ein Telefonbuchserver, der einen Web-Browser als // Benutzerschnittstelle verwendet. // // Der Server hat eine Socketschnittstelle und eine // Analysemethode. // // Die Socketschnittstelle besteht aus den beiden // Methoden vomBrowser() und zumBrowser(). Die // Analysemethode heißt analyse(). // // Eine Beschreibung der Arbeitsweise des Servers findet // sich im Grobentwurf des Lösungsbeispiels zur // Aufgabe 2. // ============================================================= import java.util.*; import java.io.*; import java.util.regex.*; import java.net.*; class TelefonbuchServer { public static void main(String[] unused) throws Exception { // Ergebnisliste bereitstellen und ServerSocket am Port 9876 // erzeugen. // --------------------------------------------------------- ArrayList<String> erg = new ArrayList<String>(); erg.add("Anfang"); String qs = null; int serverport = 9876; ServerSocket ss = new ServerSocket(serverport); Socket cs = null; // Serverstart // --------------------------------------------------------- String host = InetAddress.getLocalHost().getHostName(); System.out.println("\nTelefonbuchserver auf Host " + host + " am Port "+serverport); // GET-Requests des Browsers entgegennehmen und analysieren. // Ggf. Query String erzeugen und Suchvorgänge starten. // Ergebnis ausgeben. // --------------------------------------------------------- while(true) { if(erg.get(0).equals("Ende")) break; if(! erg.get(0).equals("Favicon")) { System.out.println("Warte auf Request"); } cs = ss.accept(); // Auf Browser Requests warten qs = vomBrowser(cs); erg = analyse(qs); zumBrowser(cs, erg); cs.close(); } ss.close(); } // main() // ============================================================= static String vomBrowser(Socket cs) throws Exception { // Aus dem Socket cs lesen, Query String ausblenden // --------------------------------------------------------- BufferedReader br = new BufferedReader( new InputStreamReader(cs.getInputStream())); String qs = br.readLine(); if(! qs.contains("/favicon.ico")) System.out.println("vom Browser->"+qs); qs = qs.replace("GET ", ""); qs = qs.replace(" HTTP/1.1", ""); if(qs.equals("/")) return qs; if(qs.equals("/favicon.ico")) return qs; qs = qs.replace("/?", ""); return qs; } // vomBrowser() // ============================================================= static ArrayList<String> analyse(String qs) throws Exception { // Ergebnisliste und Hilfsvariablen anlegen // --------------------------------------------------------- ArrayList<String> erg = new ArrayList<String>(); String regex = null; String[] token = null; String name = null; // Eingegebener Name String nummer = null; // Eingegebene Nummer String kqs = null; // Korrekt aufgebauter Query String // Query Strings, die das Telefonbuch nicht ansprechen // (1) Dialogbeginn // --------------------------------------------------------- if(qs.equals("/")) { erg.add("Anfang"); return erg; } // (2) Dialogende // --------------------------------------------------------- if(qs.endsWith("&ende=Beenden")) { erg.add("Ende"); return erg; } // (3) Favicon // --------------------------------------------------------- if(qs.equals("/favicon.ico")) { erg.add("Favicon"); return erg; } // (4) Leere Eingaben // --------------------------------------------------------- if(qs.equals("name=&nummer=")) { erg.add("Leere Eingabe"); return erg; } // URL-Kodierung rückgängig machen. // Das Programm ist unter Windows-7 entwickelt worden // --------------------------------------------------------- qs = URLDecoder.decode(qs, "ISO-8859-1"); // (5) Syntaktisch falsche Eingaben // (5.1) Fehler mit & // --------------------------------------------------------- regex = "^[^&]*&[^&]*$"; if(! qs.matches(regex)) { erg.add("Syntaxfehler"); return erg; } // (5) Syntaktisch falsche Eingaben // (5.2) Fehler mit = // --------------------------------------------------------- token = qs.split("&"); name = token[0].replace("name=", ""); nummer = token[1].replace("nummer=", ""); if(name.contains("=") || nummer.contains("=")) { erg.add("Syntaxfehler"); return erg; } // Der Query String ist korrekt aufgebaut. Jetzt werden das // Telefonbuch erzeugt, die dortigen Ergebnislisten gelöscht // und die Suche gestartet. // --------------------------------------------------------- Telefonbuch tb = new Telefonbuch(); tb.suErgNa.clear(); tb.suErgNu.clear(); kqs = name + "&" + nummer; erg = tb.tBuchAbfrage(kqs); erg.add("Suche"); return erg; } // analyse() // ============================================================= static void zumBrowser(Socket cs, ArrayList<String> erg) throws Exception { String art = erg.get(0); if(art.equals("Favicon")) return; // Fälle, bei denen keine Suche gestartet wurde // --------------------------------------------------------- if(art.equals("Anfang")) { schreibeKopf(cs); schreibeForm(cs); return; } if(art.equals("Ende")) { schreibeKopf(cs); schreibeEnde(cs); return; } if(art.equals("Leere Eingabe")) { schreibeKopf(cs); schreibeLeer(cs); schreibeForm(cs); return; } if(art.equals("Syntaxfehler")) { schreibeKopf(cs); schreibeSyntax(cs); schreibeForm(cs); return; } // Suche wurde gestartet // --------------------------------------------------------- int len = erg.size(); schreibeKopf(cs); if(len == 1) schreibeOhne(cs); else schreibeErg(cs, erg, len); schreibeForm(cs); } // zumBrowser() // ============================================================= // HTTP-Kopf und Anfang der HTML-Seite in den Socket schreiben // ----------------------------------------------------------- static void schreibeKopf(Socket cs) throws Exception { PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("HTTP/1.1 200 OK"); pw.println("Content-Type: text/html"); pw.println(); pw.println("<html>"); pw.println("<body>"); pw.flush(); } // schreibeKopf() // ============================================================= // HTML-Form und Seitenende in den Socket schreiben // ----------------------------------------------------------- static void schreibeForm(Socket cs) throws Exception { PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("<h2 align=center>Telefonbuchabfrage</h2>"); pw.println("<h3>Sie können nach einem Namen oder nach " +"einer Nummer<br>oder (nebenläufig) nach " +"beidem suchen.<br>In Ihren Eingaben darf kein &" +" und kein = vorkommen!</h3>"); String host = InetAddress.getLocalHost().getHostName(); int port = cs.getLocalPort(); String url = "http://"+host+":"+port; pw.println("<form method=get action=\"" + url + "\">"); pw.println("<table>"); pw.println("<tr>"); pw.println("<td>Name:</td>"); pw.println("<td><input name=name></td>"); pw.println("<td></td>"); pw.println("</tr>"); pw.println("<tr>"); pw.println("<td>Nummer:</td>"); pw.println("<td><input name=nummer></td>"); pw.println("<td></td>"); pw.println("</tr>"); pw.println("<tr>"); pw.println("<td><input type=submit value=Abschicken></td>"); pw.println("<td><input type=reset></td>"); pw.println("<td><input type=submit name=ende value=Beenden></td>"); pw.println("</tr>"); pw.println("</table>"); pw.println("</form>"); pw.println("</body>"); pw.println("</html>"); pw.flush(); } // schreibeForm() // ============================================================= // HTML-Endeseite in den Socket schreiben // ----------------------------------------------------------- static void schreibeEnde(Socket cs) throws Exception { PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("<h2>Ende der Telefonbuchabfrage</h2>"); pw.println("<h2>Auf Wiedersehen!</h2>"); pw.println("</body>"); pw.println("</html>"); pw.flush(); } // schreibeEnde() // ============================================================= // Schreiben bei leeren Eingaben // ----------------------------------------------------------- static void schreibeLeer(Socket cs) throws Exception { PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("<h2>Ihre Eingaben waren leer!</h2>"); pw.println("<h2>   Bitte wiederholen!</h2>"); pw.println("<h2>====================================</h2>"); pw.println("<br>"); pw.flush(); } // schreibeLeer() // ============================================================= // Schreiben bei Syntaxfehler // ----------------------------------------------------------- static void schreibeSyntax(Socket cs) throws Exception { PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("<h2>Ihre Eingaben waren fehlerhaft!</h2>"); pw.println("<h2>Bitte kein & und kein = eingeben!</h2>"); pw.println("<h2>====================================</h2>"); pw.println("<br>"); pw.flush(); } // schreibeSyntax() // ============================================================= // Schreiben bei leerem Ergebnis // ----------------------------------------------------------- static void schreibeOhne(Socket cs) throws Exception { PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("<h2>Ihre Suche hatte leider keine Treffer!</h2>"); pw.println("<h2></h2>"); pw.println("<h2>====================================</h2>"); pw.println("<br>"); pw.flush(); } // schreibeOhne() // ============================================================= // Schreiben bei nicht leerem Ergebnis // ----------------------------------------------------------- static void schreibeErg(Socket cs, ArrayList<String> erg, int len) throws Exception { String[] token = null; PrintWriter pw = new PrintWriter(cs.getOutputStream()); pw.println("<h2>Ihre Suche hat folgendes Ergebnis:</h2>"); pw.println("<h2></h2>"); len--; pw.println("<table>"); pw.println("<tr><th>Name</th><th>Nummer</th></tr>"); for(int i=0; i<len; i++) { token = erg.get(i).split("&"); pw.println("<tr><td>" + token[0] + "</td>"); pw.println("<td>" + token[1] + "</td></tr>"); } pw.println("</table>"); pw.println("<h2>====================================</h2>"); pw.flush(); } // schreibeErg() } // class

Zurück zum Manuskript