CodeGym /Kurse /Java Server /HTTP Request: method, headers, body

HTTP Request: method, headers, body

Java Server
Level 6, Lektion 1
Verfügbar

1. Request – mehr als nur ein „Link“

Wenn Sie lange in der Browser-Welt gelebt haben, ist es leicht, in die Falle zu tappen: Es scheint, als sei das Wichtigste der URL. So nach dem Motto: „Hier ist die Adresse, der Server wird es schon verstehen.“ Aber die Backend-Welt lebt nicht in einer Welt der „Links“, sondern in einer Welt der Nachrichten. In diesen Nachrichten ist der URL nur ein Teil, und nicht immer in voller Form. Der Sinn einer Anfrage wird nicht nur dadurch bestimmt, wohin Sie kommen, sondern auch was Sie zu tun bitten und welche Bedingungen Sie mitbringen.

Stellen Sie sich vor, der URL ist die Adresse auf einem Umschlag, und die HTTP-Anfrage ist der gesamte Brief: Es gibt eine „Art des Briefes“, es gibt „Vermerke auf dem Umschlag“ und manchmal einen Anhang. Wenn Sie nur die Adresse lesen, sind Sie ungefähr wie ein Briefträger, der den Brief brav zugestellt hat, aber nie verstanden hat, dass darin die Forderung „Geben Sie das Geld zurück“ oder „Senden Sie den Katalog“ steht.

Aus Sicht eines Backend-Entwicklers ist die HTTP-Anfrage eine strukturierte Nachricht, die man normalerweise in vier Blöcke zerlegen kann: die Startzeile mit dem method, eine Reihe von headers, eine leere Trennzeile und der body, der fehlen kann. Und es ist wichtig, diese Struktur vor allen bequemen Abstraktionen zu erkennen – sonst vertrauen Sie beim Debuggen eher der Benutzeroberfläche des Tools als der Realität.

2. Anatomie der Anfrage: Teile

Am besten stellt man sich eine HTTP-Anfrage als „Textdatei“ mit einem strengen Format vor. Ja, in der Realität gibt es viele Protokolldetails, aber auf Ihrer jetzigen Ebene brauchen Sie ein brauchbares, ruhiges Modell. Es sollte Ihnen helfen, Anfragen in Postman zu lesen, zu verstehen, was bei Integrationen passiert, und nicht den Kopf zu verlieren, wenn etwas schiefgeht.

In allgemeiner Form sieht eine Anfrage so aus:

<request-line>
<header-name>: <header-value>
<header-name>: <header-value>
...

<body (optional)>

Und nun etwas konkreter mit visueller Trennung:

<method> <path-with-query> HTTP/1.1
Header-1: value
Header-2: value

<bytes of body, may be empty>

Achten Sie auf zwei Dinge. Erstens: Die Header sind Zeilen der Form Name: Wert. Zweitens: Zwischen den Headern und dem Body gibt es eine Leerzeile. Das ist nicht „zur Verschönerung“, sondern Teil des Formats: Genau daran erkennen viele Tools, wo die Header enden und der Body beginnt.

Um das Ganze zu festigen, fassen wir die Teile der Anfrage in einer kleinen Tabelle zusammen – nicht als Prüfung, sondern als „Spickzettel für den Kopf“:

Teil der Anfrage Wie es aussieht Wozu es dient
request line
GET /api/v1/reading-list HTTP/1.1
Gibt schnell die „Art“ der Anfrage (method) und das Ziel (path/query) an
headers
Host: localhost:8080
Metadaten: Datenformat, Client-Identität, Erwartungen, technische Parameter
Leerzeile einfach ein Zeilenumbruch Trennt Header und Body
body (manchmal) JSON / Text / Bytes Nutzlast: Daten zum Erstellen, Aktualisieren usw.

Im Rahmen unseres Projekts ReadLater Starter werden Sie all diese Teile antreffen. Auch wenn wir noch keinen Server schreiben, können Sie jetzt bereits lernen, eine Anfrage so zu lesen, wie Ihr Backend sie lesen wird: zuerst Methode und Pfad, dann Header, und erst dann – den Body, falls vorhanden.

3. Startzeile: Methode, Ziel, Version

Die Startzeile einer HTTP-Anfrage ist wie der Betreff eines Briefes: kurz, aber sehr informativ. Sie steht ganz vorne, und wenn Sie lernen, sie sicher zu lesen, wird es Ihnen viel leichter fallen, sich in jeder Anfrage zurechtzufinden – ob eingehend oder ausgehend. Viele Anfänger schauen sofort auf den Body, weil „da die Daten sind“, aber das ist, als würde man einen Vertrag ab der Mitte lesen und die erste Seite mit den Bedingungen überspringen.

method: Ein Wort, das den gesamten Sinn der Anfrage verändert

method ist eine kurze Markierung, die dem Server mitteilt, um welche Art von Nachricht es sich handelt. Sie müssen jetzt nicht in die „korrekte Semantik“ aller Methoden eintauchen – wichtig ist der grundlegende Gedanke: Derselbe Pfad kann bei unterschiedlichen Methoden völlig unterschiedliche Absichten des Clients bedeuten.

  • GET /api/v1/reading-list – „gib mir Daten“
  • POST /api/v1/reading-list – „nimm Daten entgegen“ (normalerweise im Body)

Selbst wenn der Pfad identisch ist, kann der Server nicht „nach Stimmung raten“. Method ist Teil des Vertrags, kein dekorativer Aufkleber.

Minidemo in Java, nur damit Sie sich optisch daran gewöhnen, dass die Methode eine eigenständige Entität ist:

// Pfad des Endpunkts (Ziel der Anfrage in der request line)
String path = "/api/v1/reading-list";

// Startzeilen desselben Pfads, aber mit unterschiedlichen Methoden
String first = "GET " + path + " HTTP/1.1";
String second = "POST " + path + " HTTP/1.1";

// Zum visuellen Lesen: Die Methode ändert den Sinn der Anfrage bei gleichem Pfad
System.out.println(first);   // GET /api/v1/reading-list HTTP/1.1
System.out.println(second);  // POST /api/v1/reading-list HTTP/1.1

Das sieht primitiv aus, aber methodisch ist es wichtig: nicht „Anfrage an diesen Pfad“, sondern „Anfrage mit dieser Methode an diesen Pfad“.

Ziel der Anfrage: Pfad und Query

In der Startzeile steht normalerweise nicht die vollständige URL der Form https://.... Meistens ist es der Pfad, manchmal zusammen mit der Query-Zeichenfolge. Und das ist logisch: Der Server muss (im typischen Fall) nicht, dass Sie „https://host:port“ direkt in der Anfragezeile wiederholen – er weiß ja, dass Sie zu ihm gekommen sind.

Es ist nützlich, eine Darstellung in die andere zu überführen. Wenn der Client von der vollständigen URL https://catalog.readlater.local:8443/search?q=clean%20code startet, dann wird in der typischen HTTP/1.1 request line GET /search?q=clean%20code HTTP/1.1 stehen, Host zusammen mit dem expliziten Port, falls angegeben, geht in Host: catalog.readlater.local:8443, und scheme beeinflusst bereits die Art der Verbindung vor dem Senden der Anfrage. Das heißt, die Teile des URL verschwinden nicht – sie werden nur zwischen request line, Headern und Verbindungskontext aufgeteilt.

Beispiel einer Startzeile mit Query:

GET /api/v1/reading-list?status=PLANNED HTTP/1.1

Sie können bereits path und query aus einer URL extrahieren. Hier ist es dieselbe Fähigkeit, nur dass das Ziel der Anfrage direkt in der request line lebt.

HTTP-Version: Was bedeutet HTTP/1.1

Die Protokollversion am Ende der Startzeile sieht ein wenig wie ein „Zauberspruch“ aus, aber auf alltäglicher Ebene ist der Sinn einfach: Client und Server müssen sich einigen, in welchem „HTTP-Dialekt“ sie sprechen. Meistens werden Sie HTTP/1.1 sehen, weil das lange die am weitesten verbreitete Variante war.

Heutzutage gibt es neuere Versionen (z. B. HTTP/2, HTTP/3), aber unser Ziel ist nicht, sie intern zu vergleichen, sondern zu verstehen, dass die Version ein Teil des Nachrichtenformats ist. Für einen Backend-Entwickler bedeutet das: Wenn Sie eine rohe Nachricht sehen, wundern Sie sich nicht über den Anhang HTTP/1.1 – das ist kein „überflüssiger Müll“, sondern ein Teil der Vereinbarung.

4. Headers: Metadaten der Anfrage

Headers (Kopfzeilen) wirken oft wie langweilige „Protokollzeilen“, und ein Anfänger denkt nicht selten: „Ach ja, da ist irgendwas Technisches, ich will den Body sehen.“ In der realen Backend-Welt führt das zu merkwürdigen Bugs: Man hat alles scheinbar richtig gesendet, aber der Server antwortet im falschen Format, der Client versteht die Antwort nicht, oder es stellt sich heraus, dass der Server nicht verstanden hat, was Sie ihm geschickt haben.

Ein Header ist eine Zeile der Form Name: Wert. Es können viele Header sein, sie übertragen Metadaten der Anfrage. Es ist wichtig, nicht alle auswendig zu lernen, sondern sich an den Gedanken zu gewöhnen: Headers sind ein separater Informationskanal, der weder durch URL noch durch body ersetzt wird.

Hier ist ein Beispiel einer „minimal realitätsnahen“ Anfrage ohne Body, bei der es trotzdem Header gibt:

// Achten Sie auf die Zeilenenden: \r + Zeilenumbruch im Textblock => CRLF (\r\n)
String rawRequest = """
GET /health HTTP/1.1\r
Host: localhost:8080\r
Accept: application/json\r
\r
""";

// Drucken Sie die „rohe“ Anfrage vollständig, um die Struktur zu sehen: request line -> headers -> Leerzeile
System.out.println(rawRequest);

Hier sagt Host, zu welchem Host die Anfrage gehört (bei HTTP/1.1 ein wichtiger Teil), und Accept deutet an, welches Antwortformat der Client bevorzugt. Wir machen daraus jetzt keine separate Lektion über bestimmte Header, aber es ist wichtig, das Gefühl zu bekommen: „Aha, diese Zeilen bedeuten tatsächlich etwas.“

Ein etwas „körperlicheres“ Beispiel, in dem ein Body auftaucht (wir schauen uns nur die Form an), und dann tauchen Header auf, die mit dem Body zusammenhängen:

// Body der Anfrage (Payload), der NACH der Leerzeile kommt
String body = "{\"title\":\"Clean Code\",\"author\":\"Robert C. Martin\"}";

// Header enden mit der Leerzeile \r\n\r\n, danach kommt der Body
String rawRequest = """
POST /api/v1/reading-list HTTP/1.1\r
Host: localhost:8080\r
Content-Type: application/json\r
\r
""" + body;

// Wichtig: Content-Type erklärt dem Server, wie die Bytes des Bodys zu interpretieren sind
System.out.println(rawRequest);

Hier teilt Content-Type dem Server mit, wie der Body zu interpretieren ist. Und wieder: Sie müssen jetzt nicht alle Varianten auswendig lernen, aber das Prinzip verstehen – ein Body ohne „Formatbeschreibung“ wird oft zum Rätsel.

5. Body: Nutzlast der Anfrage

Der Body ist der Teil der Anfrage, in dem die Daten liegen. Aber eine wichtige Nuance: Der Body ist nicht immer vorhanden, und das Fehlen eines Bodys ist eine normale, übliche Situation. Beispielsweise kommen viele Leseanfragen (im landläufigen Sinne) gut ohne Body aus. Anfragen, bei denen Sie „Daten an den Server übermitteln“, enthalten dagegen meist einen Body.

Auf einer allgemeinen Ebene kann man den Body als „Anhang“ zu einem Brief betrachten. Die Adresse und die Methode sagen, wohin und mit welcher Absicht Sie kommen, die Header sind Notizen „in welchem Format der Anhang ist“ und „welche Bedingungen“, und der Body ist das, was Sie tatsächlich übermitteln.

Es ist auch wichtig zu bedenken: Technisch gesehen ist der Body kein „String“, sondern ein Byte-Satz. Wir werden zwar meistens Textformate sehen (insbesondere JSON), aber der Server erhält tatsächlich Bytes und versteht anhand der Header und der Protokollregeln, wie er sie zu lesen hat.

Minibeispiel für das Gefühl „der Body kann leer sein“:

// Die Leerzeile nach dem Host schließt den Header-Block ab, danach könnte ein Body kommen – aber es gibt keinen
String rawRequest = """
GET /api/v1/reading-list HTTP/1.1\r
Host: localhost:8080\r
\r
""";

System.out.println(rawRequest);

Und ein Minibeispiel „Body ist vorhanden und ein separater Teil“:

// Beispielhafter Body (z. B. ein Formular). Wichtig: Er ist NICHT Teil der URL und NICHT Teil der Header
String body = "title=Clean Code&author=Robert";

// Nach der Leerzeile beginnt der Body
String rawRequest = """
POST /notes HTTP/1.1\r
Host: readlater.local\r
\r
""" + body;

System.out.println(rawRequest);

Das Format des Bodys hier ist beispielhaft (wir gehen nicht auf spezifische Medientypen ein), aber die Idee ist wichtig: Der Body wird nicht mit den Headern vermischt und ist kein „Teil der URL“. Es ist ein separater Datenblock.

6. Rohe Anfrage: Struktur ohne Benutzeroberfläche

Tools wie Postman oder DevTools teilen die Anfrage in Registerkarten auf, und das ist praktisch. Aber es ist nützlich, wenigstens einmal ein einfaches Bild zu sehen: method + path, headers und body sind nicht drei unabhängige Entitäten, sondern Teile einer einzigen Nachricht.

Vorerst reicht diese Ansicht:

POST /api/v1/reading-list HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{"title":"Clean Code","author":"Robert C. Martin"}

Hier ist nur wichtig, zwei Dinge zu beachten: Die Startzeile kommt zuerst, die Header folgen, und eine Leerzeile trennt sie vom Body. Dieses Bild reicht aus, um sich in Logs nicht zu verlieren und nicht zu denken, der Body lebe getrennt vom Rest der Anfrage.

7. Verständnis der Anfrage vor dem Web-Framework

Man möchte am liebsten sagen: „Okay, aber ich werde ein Framework verwenden, das alles selbst analysiert.“ Und in der Tat kann ein gutes Framework automatisch die Methode lesen, die Header parsen, den Body extrahieren, in ein Objekt umwandeln usw. Aber wenn Sie die ursprüngliche Struktur nicht verstehen, geraten Sie in Abhängigkeit von Magie. Und Magie endet bekanntlich genau in dem Moment, in dem Sie ein Log öffnen und sehen: 400 Bad Request.

Das Verständnis der Anfrage ist Ihre Möglichkeit, Ingenieur zu bleiben, nicht „Knopfbediener“. Es hilft Ihnen, Verträge zu lesen, Integrationsprobleme zu verstehen und zu wissen, was Sie genau gesendet haben. Und noch ein wichtiger Grund: In der Backend-Welt treten Sie sowohl als Server als auch als Client auf. Das heißt, Sie empfangen nicht nur Anfragen, sondern senden sie auch an externe APIs. In beiden Fällen ist die Struktur der Anfrage dieselbe: method, headers, body – nur dass Sie sich auf unterschiedlichen Seiten der Leitung befinden.

Und schließlich ist es einfach gesunder Menschenverstand: Wenn Sie ein Kommunikationssystem zwischen Programmen aufbauen, sollten Sie in der Lage sein, die „Briefe“ zu lesen, die sie austauschen, und nicht nur die Knöpfe im E-Mail-Client.

8. Minidemo in Java: Anfrage in Teilen

Wir brauchen jetzt weder einen vollständigen Client noch einen manuellen HTTP-Parser. Aber es ist nützlich, einmal zu sehen, dass in einer rohen Anfrage die erste Zeile genau die request line ist und dass es normalerweise am einfachsten ist, mit dem Lesen dort zu beginnen.

// Für einen ersten Blick auf eine rohe Anfrage reicht oft die erste Zeile: Methode + Ziel + Version
String headersPart = """
GET /health HTTP/1.1\r
Host: localhost:8080\r
Accept: application/json\r
""";

// Die erste Zeile ist die request line
String requestLine = headersPart.split("\r\n")[0];
System.out.println(requestLine); // GET /health HTTP/1.1

Das ist keine Vorlage für die Implementierung eines eigenen HTTP-Parsers. Wichtig ist hier die Gewohnheit: Zuerst method + path/query + version sehen, und dann auf die Header und den Body schauen.

9. Typische Fehler bei der Arbeit mit HTTP-Anfragen

Fehler Nr. 1: URL und HTTP-Anfrage verwechseln, denken, „Anfrage = Link“.
URL ist zwar wichtig, aber nur für die Adressierung zuständig. In einer echten Anfrage gibt es method, headers und manchmal body. Wenn Sie die method vergessen, werden Sie sich wundern, warum der Server „auf dieselbe Adresse“ unterschiedlich reagiert. Aber er reagiert nicht „unterschiedlich“, er hat nur verschiedene Nachrichten erhalten.

Fehler Nr. 2: Die Anfrage nur nach dem Body lesen und Methode und Header ignorieren.
Das ist eine klassische Angewohnheit aus der Welt „mir sind die Daten wichtig“. In der Praxis kann der Server anhand der Header entscheiden, wie der Body zu lesen ist, oder sich sogar weigern, ihn zu lesen, wenn das Format nicht den Erwartungen entspricht. Und die method gibt die Art der Operation vor. Wenn Sie nur den Body betrachten, verlieren Sie die Hälfte der Bedeutung der Anfrage.

Fehler Nr. 3: Erwarten, dass der Body immer vorhanden ist.
Viele Anfragen haben keinen Body, und das ist normal. Wenn Sie im Voraus sicher sind, dass ein Body vorhanden sein muss, beginnen Sie dort „nach Daten zu suchen“, wo keine sind, und ziehen seltsame Schlüsse wie „der Server hat eine leere Anfrage gesendet“ – obwohl die Anfrage völlig vollständig war.

Fehler Nr. 4: Die Leerzeile zwischen Headern und Body in der Rohform nicht beachten.
In Benutzeroberflächen ist das versteckt, aber im rohen Text ist die Leerzeile eine Grenze. Wenn Sie jemals manuell eine Anfrage zusammenbauen (oder ein Log/Dump lesen) und diese Grenze nicht sehen, werden Sie leicht verwechseln, wo die Header enden und der Body beginnt.

Fehler Nr. 5: Denken, dass Header „unwichtige technische Zeilen“ sind.
Header sind Teil des Vertrags. Sie tragen Metadaten: wer der Client ist, was er erwartet, in welchem Format die Daten sind und vieles mehr. Sie müssen nicht alle Header auswendig kennen, aber Sie müssen wissen, dass es sie gibt und dass sie die Bedeutung der Kommunikation verändern können. Das ist wie die Kleingedrucktes in einem Vertrag: Ja, es ist mühsam zu lesen, aber später zu staunen tut noch mehr weh.

1
Aufgabe
Java Server, Level 6, Lektion 1
Gesperrt
Modell einer einfachen HTTP-Anfrage
Modell einer einfachen HTTP-Anfrage
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION