Von Jamal Hassan, Backend Developer bei Java Fleet Systems Consulting
Mit Einblicken von Elyndra Valen (Senior Dev) und Nova Trent (Junior Dev)
Schwierigkeit: 🔴 Fortgeschritten
Lesezeit: 45 Minuten
Voraussetzungen: Java Grundlagen, Multithreading Basics
Kurs: Java Erweiterte Techniken – Tag 10 von 10
📖 Java Erweiterte Techniken – Alle Tage
📍 Du bist hier: Tag 10 – Der Abschluss! 🎉
⚡ Das Wichtigste in 30 Sekunden
Dein Problem: Sockets Du musst mit anderen Systemen kommunizieren – APIs aufrufen, Server bauen, Daten übertragen.
Die Lösung: Java’s Netzwerk-APIs – von Low-Level Sockets bis zum modernen HTTP-Client.
Heute lernst du:
- ✅ TCP/IP Grundlagen verstehen
- ✅ Sockets für Client-Server-Kommunikation
- ✅ Der moderne
HttpClient(Java 11+) - ✅ REST-APIs aufrufen und JSON verarbeiten
- ✅ Asynchrone HTTP-Requests
- ✅ WebSockets für Echtzeit-Kommunikation
👋 Jamal: „Willkommen zum Finale!“
Hi! 👋
Jamal hier für den letzten Tag unserer Reise. Netzwerkprogrammierung ist das, was moderne Anwendungen erst möglich macht – von Microservices über REST-APIs bis zu Chat-Anwendungen.
Was wir heute bauen:
- Einen einfachen Chat-Server und Client
- REST-API Calls mit dem HttpClient
- JSON-Verarbeitung
Los geht’s!
🖼️ Netzwerk-Architektur

Abbildung 1: TCP/IP, Sockets und HTTP
🟢 GRUNDLAGEN
TCP/IP in 2 Minuten
| Schicht | Protokoll | Java-Klasse |
|---|---|---|
| Anwendung | HTTP, FTP, SMTP | HttpClient, URL |
| Transport | TCP, UDP | Socket, DatagramSocket |
| Internet | IP | InetAddress |
| Netzwerk | Ethernet, WiFi | (OS-Ebene) |
TCP vs. UDP:
- TCP: Zuverlässig, verbindungsorientiert (HTTP, E-Mail)
- UDP: Schnell, verbindungslos (Gaming, Streaming)
Socket-Grundlagen
Ein Socket ist ein Endpunkt für Netzwerkkommunikation.
// Server erstellen
ServerSocket serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept(); // Blockiert bis Client verbindet
// Client verbinden
Socket socket = new Socket("localhost", 8080);
// Daten senden/empfangen
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
Einfacher Echo-Server
public class EchoServer {
public static void main(String[] args) throws IOException {
int port = 8080;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server läuft auf Port " + port);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Client verbunden: " + clientSocket.getInetAddress());
// In separatem Thread behandeln
new Thread(() -> handleClient(clientSocket)).start();
}
}
}
private static void handleClient(Socket socket) {
try (
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)
) {
String line;
while ((line = in.readLine()) != null) {
System.out.println("Empfangen: " + line);
out.println("Echo: " + line); // Zurücksenden
if (line.equalsIgnoreCase("bye")) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Einfacher Echo-Client
public class EchoClient {
public static void main(String[] args) throws IOException {
String host = "localhost";
int port = 8080;
try (
Socket socket = new Socket(host, port);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader console = new BufferedReader(
new InputStreamReader(System.in))
) {
System.out.println("Verbunden mit Server. Tippe Nachrichten:");
String userInput;
while ((userInput = console.readLine()) != null) {
out.println(userInput); // An Server senden
String response = in.readLine(); // Antwort lesen
System.out.println("Server: " + response);
if (userInput.equalsIgnoreCase("bye")) {
break;
}
}
}
}
}
🟡 PROFESSIONALS
Der moderne HttpClient (Java 11+)
Vergiss HttpURLConnection! Der neue HttpClient ist elegant und modern:
import java.net.http.*;
import java.net.URI;
// Client erstellen (wiederverwendbar!)
HttpClient client = HttpClient.newHttpClient();
// Request bauen
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/users/octocat"))
.header("Accept", "application/json")
.GET()
.build();
// Synchron senden
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
GET, POST, PUT, DELETE
HttpClient client = HttpClient.newHttpClient();
// ===== GET =====
HttpRequest getRequest = HttpRequest.newBuilder()
.uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
.GET()
.build();
// ===== POST =====
String jsonBody = """
{
"title": "Mein Post",
"body": "Inhalt hier",
"userId": 1
}
""";
HttpRequest postRequest = HttpRequest.newBuilder()
.uri(URI.create("https://jsonplaceholder.typicode.com/posts"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
// ===== PUT =====
HttpRequest putRequest = HttpRequest.newBuilder()
.uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
// ===== DELETE =====
HttpRequest deleteRequest = HttpRequest.newBuilder()
.uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
.DELETE()
.build();
Asynchrone Requests
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/users/octocat"))
.build();
// Asynchron senden - blockiert NICHT!
CompletableFuture<HttpResponse<String>> future =
client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
// Callback wenn fertig
future.thenAccept(response -> {
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
});
// Andere Arbeit machen...
System.out.println("Request läuft im Hintergrund...");
// Warten falls nötig
future.join();
Mehrere Requests parallel
HttpClient client = HttpClient.newHttpClient();
List<String> urls = List.of(
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3"
);
// Alle parallel starten
List<CompletableFuture<String>> futures = urls.stream()
.map(url -> HttpRequest.newBuilder()
.uri(URI.create(url))
.build())
.map(request -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body))
.toList();
// Auf alle warten
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.join();
// Ergebnisse ausgeben
futures.forEach(f -> System.out.println(f.join().substring(0, 50) + "..."));
HttpClient konfigurieren
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // HTTP/2 bevorzugen
.followRedirects(HttpClient.Redirect.NORMAL) // Redirects folgen
.connectTimeout(Duration.ofSeconds(10)) // Timeout
.executor(Executors.newFixedThreadPool(5)) // Thread-Pool
.build();
// Mit Timeout pro Request
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.timeout(Duration.ofSeconds(30))
.build();
JSON verarbeiten (ohne externe Library)
Für einfache Fälle geht’s auch ohne Jackson/Gson:
// JSON parsen mit Pattern Matching (einfach)
String json = """
{"name": "Max", "age": 25}
""";
// Mit Regex (nur für einfache Fälle!)
Pattern namePattern = Pattern.compile("\"name\"\\s*:\\s*\"([^\"]+)\"");
Matcher matcher = namePattern.matcher(json);
if (matcher.find()) {
String name = matcher.group(1);
System.out.println("Name: " + name);
}
// Besser: Records für Typsicherheit + manuelle Parsing
record Person(String name, int age) {
static Person fromJson(String json) {
// Vereinfachtes Parsing
String name = extractString(json, "name");
int age = extractInt(json, "age");
return new Person(name, age);
}
private static String extractString(String json, String key) {
Pattern p = Pattern.compile("\"" + key + "\"\\s*:\\s*\"([^\"]+)\"");
Matcher m = p.matcher(json);
return m.find() ? m.group(1) : "";
}
private static int extractInt(String json, String key) {
Pattern p = Pattern.compile("\"" + key + "\"\\s*:\\s*(\\d+)");
Matcher m = p.matcher(json);
return m.find() ? Integer.parseInt(m.group(1)) : 0;
}
}
💡 Tipp: Für echte Projekte nutze Jackson oder Gson!
🔵 BONUS
URL und URI
// URL - für Netzwerk-Ressourcen
URL url = new URL("https://example.com:8080/path?query=value");
System.out.println("Protocol: " + url.getProtocol()); // https
System.out.println("Host: " + url.getHost()); // example.com
System.out.println("Port: " + url.getPort()); // 8080
System.out.println("Path: " + url.getPath()); // /path
System.out.println("Query: " + url.getQuery()); // query=value
// URI - für Identifikation (auch nicht-Netzwerk)
URI uri = URI.create("mailto:test@example.com");
URI uri2 = URI.create("file:///home/user/file.txt");
InetAddress – IP-Adressen
// Hostname auflösen
InetAddress address = InetAddress.getByName("google.com");
System.out.println("IP: " + address.getHostAddress());
// Eigene Adresse
InetAddress localhost = InetAddress.getLocalHost();
System.out.println("Mein Host: " + localhost.getHostName());
System.out.println("Meine IP: " + localhost.getHostAddress());
// Erreichbarkeit prüfen
boolean reachable = address.isReachable(5000); // 5 Sekunden Timeout
System.out.println("Erreichbar: " + reachable);
UDP mit DatagramSocket
// UDP Server
public class UDPServer {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9876);
byte[] buffer = new byte[1024];
System.out.println("UDP Server läuft...");
while (true) {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet); // Blockiert
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("Empfangen: " + message);
// Antwort senden
String response = "ACK: " + message;
byte[] responseData = response.getBytes();
DatagramPacket responsePacket = new DatagramPacket(
responseData, responseData.length,
packet.getAddress(), packet.getPort()
);
socket.send(responsePacket);
}
}
}
// UDP Client
public class UDPClient {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName("localhost");
String message = "Hallo UDP!";
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, 9876);
socket.send(packet);
// Antwort empfangen
byte[] buffer = new byte[1024];
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
System.out.println("Antwort: " + new String(response.getData(), 0, response.getLength()));
socket.close();
}
}
Multi-Client Server mit ExecutorService
public class MultiClientServer {
private static final int PORT = 8080;
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server läuft auf Port " + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
executor.execute(new ClientHandler(clientSocket));
}
}
}
}
class ClientHandler implements Runnable {
private final Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)
) {
out.println("Willkommen! Deine ID: " + Thread.currentThread().getName());
String line;
while ((line = in.readLine()) != null) {
System.out.println("[" + Thread.currentThread().getName() + "] " + line);
out.println("Echo: " + line);
if ("bye".equalsIgnoreCase(line)) break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
💬 Real Talk: Netzwerk-Fallen
Java Fleet Büro, Freitag 17:00. Letzte Debugging-Session.
Nova: „Mein Server stürzt ab wenn ein Client sich plötzlich trennt!“
Jamal: „Klassiker! Du musst Exceptions behandeln und Ressourcen schließen:“
try (Socket socket = clientSocket) {
// Kommunikation
} catch (IOException e) {
System.out.println("Client disconnected: " + e.getMessage());
}
// Socket wird automatisch geschlossen
Nova: „Und mein HttpClient hängt manchmal…“
Elyndra: „Immer Timeouts setzen!“
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://slow-api.com"))
.timeout(Duration.ofSeconds(30))
.build();
Jamal: „Und vergiss nicht: HttpClient ist wiederverwendbar! Nicht für jeden Request neu erstellen.“
// ❌ FALSCH - für jeden Request neu
for (String url : urls) {
HttpClient client = HttpClient.newHttpClient(); // Overhead!
// ...
}
// ✅ RICHTIG - einmal erstellen
HttpClient client = HttpClient.newHttpClient();
for (String url : urls) {
// client wiederverwenden
}
❓ FAQ
Frage 1: Socket vs. HttpClient – wann was?
| Socket | HttpClient |
|---|---|
| Low-Level | High-Level |
| Eigenes Protokoll | HTTP/HTTPS |
| Chat, Gaming | REST APIs |
| Volle Kontrolle | Einfacher |
Frage 2: Synchron vs. Asynchron?
Synchron:
- Blockiert bis Antwort da
- Einfacher zu verstehen
- OK für wenige Requests
Asynchron:
- Blockiert nicht
- Besser für viele parallele Requests
- Komplexer (Callbacks, Futures)
Frage 3: Wie handle ich JSON richtig?
Für echte Projekte:
- Jackson – Industrie-Standard
- Gson – von Google, einfacher
- JSON-B – Jakarta EE Standard
// Mit Jackson (Dependency hinzufügen!) ObjectMapper mapper = new ObjectMapper(); Person person = mapper.readValue(jsonString, Person.class); String json = mapper.writeValueAsString(person);
Frage 4: Wie sichere ich Verbindungen ab?
// HTTPS ist Standard mit HttpClient
HttpClient client = HttpClient.newHttpClient();
// Automatisch HTTPS wenn URI mit https:// beginnt
// Für Sockets: SSLSocket
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) factory.createSocket("secure.example.com", 443);
Frage 5: Bernd sagt, REST sei „übertrieben“?
seufz REST ist der De-facto-Standard für APIs weil:
- Einfach und verständlich
- Stateless = Skalierbar
- HTTP-Verben (GET, POST, PUT, DELETE)
- Universell unterstützt
🔍 „behind the code“ oder „in my feels“? Die echten Geschichten findest du, wenn du weißt wo du suchen musst…
🎁 Cheat Sheet
🟢 Sockets
// Server
ServerSocket server = new ServerSocket(port);
Socket client = server.accept();
// Client
Socket socket = new Socket(host, port);
// I/O
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
🟡 HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.GET() / .POST(BodyPublishers.ofString(json))
.timeout(Duration.ofSeconds(30))
.build();
// Sync
HttpResponse<String> response = client.send(request,
BodyHandlers.ofString());
// Async
client.sendAsync(request, BodyHandlers.ofString())
.thenAccept(response -> /* ... */);
🔵 Nützliche Klassen
URI.create("https://example.com")
URL url = new URL("https://example.com")
InetAddress.getByName("hostname")
InetAddress.getLocalHost()
🎨 Challenge für dich!
🟢 Level 1 – Einsteiger
- [ ] Baue einen Echo-Server der Nachrichten zurücksendet
- [ ] Rufe eine öffentliche API mit HttpClient auf
- [ ] Gib den HTTP-Status-Code und Body aus
Geschätzte Zeit: 30-40 Minuten
🟡 Level 2 – Fortgeschritten
- [ ] Erweitere den Server für mehrere Clients
- [ ] Implementiere POST-Requests mit JSON-Body
- [ ] Verarbeite die JSON-Antwort
Geschätzte Zeit: 45-60 Minuten
🔵 Level 3 – Profi
- [ ] Baue einen einfachen Chat-Server mit Broadcast
- [ ] Implementiere parallele API-Calls mit CompletableFuture
- [ ] Füge Timeout-Handling hinzu
Geschätzte Zeit: 60-90 Minuten
📦 Downloads
| Projekt | Für wen? | Download |
|---|---|---|
| tag10-netzwerk-starter.zip | 🟢 Mit TODOs | ⬇️ Download |
| tag10-netzwerk-complete.zip | 🟡 Musterlösung | ⬇️ Download |
🔗 Weiterführende Links
🇩🇪 Deutsch
| Ressource | Beschreibung |
|---|---|
| Rheinwerk: Netzwerk | Umfassendes Kapitel |
🇬🇧 Englisch
| Ressource | Beschreibung | Level |
|---|---|---|
| Oracle: Networking | Offizielle Doku | 🟢 |
| Baeldung: HttpClient | Praxisbeispiele | 🟡 |
| Java HttpClient Docs | API-Referenz | 🟡 |
🎉 GESCHAFFT! Der Kurs ist komplett!
Was du in 10 Tagen gelernt hast:
✅ Tag 1-2: Collections – Listen, Sets, Maps
✅ Tag 3: Generics für typsicheren Code
✅ Tag 4-5: Lambdas und Functional Interfaces
✅ Tag 6: Stream-API für elegante Datenverarbeitung
✅ Tag 7: File I/O und Properties
✅ Tag 8: Annotations und Multithreading Basics
✅ Tag 9: Thread-Synchronisation
✅ Tag 10: Netzwerkprogrammierung
Du bist jetzt bereit für:
- Spring Boot
- Microservices
- Enterprise Java
- Oder was auch immer du bauen willst!
👋 Bis zum nächsten Kurs!
Fragen? jamal.hassan@java-developer.online
Das ganze Team:
- Elyndra Valen (Senior Dev)
- Jamal Hassan (Backend)
- Nova Trent (Junior, jetzt nicht mehr so junior 😉)
- Und natürlich Bernd (der Skeptiker)
Tags: #Java #Networking #Sockets #HttpClient #REST #API #Tutorial
📚 Das könnte dich auch interessieren
© 2025 Java Fleet Systems Consulting | java-developer.online

