====== Http-Requests ====== Mithilfe der Klassen ''HttpClient'', ''HttpRequest'' und ''HttpResponse'' können von der Online-IDE aus http(s)-Anfragen gesendet werden. Es sind sowohl GET- als auch POST-Requests möglich. Die Benutzung der Klassen wird durch die Beispiele unten erklärt. **Beschränkung durch die Same-Origin-Policy der Server** \\ \\ Da die Online-IDE im Browser läuft, werden die http(s)-Requests aus der Webseite heraus per [[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch|Javascript Fetch-API]] generiert. Origin der Anfragen ist daher https://www.learnj.de bzw. https://www.online-ide.de. Viele Server gestatten leider keine Requests von einem Origin, der nicht ihrer eigenen Domain entspricht (SOP = "same origin policy"). Von der Online-IDE aus können daher nur Daten von Servern abgerufen werden, die einen offenen [[https://de.wikipedia.org/wiki/Cross-Origin_Resource_Sharing|CORS-Header]] gesetzt haben (''Access-Control-Allow-Origin: *''). \\ \\ **Sammlung freier offener APIs** \\ Es ist gar nicht so einfach, gute freie APIs für den Unterricht zu finden. Hier [[.apis:start|finden Sie eine kleine Sammlung.]] \\ \\ Falls Sie selbst eine gute, freie, von der Online-IDE aus erreichbare API kennen, die noch nicht in dieser Sammlung enthalten ist, würde ich mich über einen Tipp von Ihnen freuen! ===== Durchschnittseinkommen in den USA nach Branche ===== Viele Daten über die USA erhält man auf der Seite [[https://datausa.io|https://datausa.io]]. Das öffentliche API [[https://datausa.io/about/api/|ist hier beschrieben.]] Wir holen uns Daten über das jährliche Durchschnittseinkommen in Abhängigkeit von der Branche:
===== URL-Encoding ===== Gemäß [[https://www.rfc-editor.org/rfc/rfc3986#page-12|RFC3986]] darf man für die Parameter eines GET-Requests (d.h. alles nach dem '?') nur einen Teil der ASCII-Zeichen verwenden. Alle anderen Zeichen (Leerzeichen, Schrägstrich, Umlaute, ...) müssen in einer Schreibweise mit Prozentzeichen enkodiert werden. Statt measure=Average Wage,Average Wage Appx MOE,Record Count&drilldowns=Major Occupation Group&Workforce Status=true&Record Count>=5 muss man also schreiben: measure=Average%20Wage,Average%20Wage%20Appx%20MOE,Record%20Count&drilldowns=Major%20Occupation%20Group&Workforce%20Status=true&Record%20Count>=5 Damit wir diese Enkodierung nicht von Hand erledigen müssen, gibt es die Klasse ''URLEncoder'', deren Anwendung im folgenden Beispiel gezeigt wird.
===== Aufbereiten der Json-Daten (JsonParser) ===== Die Ausgabe liegt im Json-Format vor. Zum Aufbereiten nutzen wir die JsonParser-Klasse der Online-IDE. Sie konvertiert die Json-Zeichenkette in einen Objektbaum. Wir betrachten zunächst den Beginn der Zeichenkette: {"data": [ { "ID Major Occupation Group":"110000-290000", "Major Occupation Group":"Management, business, science, & arts occupations", "ID Year":2020, "Year":"2020", "ID Workforce Status":true, "Workforce Status":"true", "Average Wage":81574.98386970875, "Average Wage Appx MOE":268.2938957859685, "Record Count":2816397, "Slug Major Occupation Group":"management-business-science-arts-occupations" }, { "ID Major Occupation Group":"310000-390000", "Major Occupation Group":"Service Occupations", "ID Year":2020, "Year":"2020", usw... Die führende öffnende geschweifte Klammer ('{') zeigt uns, dass das root-Element der Json-Daten ein Objekt ist. Es enthält nur ein einziges Attribut mit dem Bezeichner 'data', das wiederum ein Array ist (das zeigt die eckige Klammer). Im Array enthalten sind lauter gleichartige Objekte mit den Attributen '"ID Major Occupation Group"', '"ID Year"' usw. Wir wollen uns von all diesen Objekten nur die Werte der Attribute '"Major Occupation Group"' und '"Average Wage"' holen und ausgeben. Dazu nutzen wir die Klasse ''JsonParser'', die uns die Json-Zeichenkette in einen Objektbaum verwandelt, dessen Knoten aus ''JsonElement''-Objekten bestehen. Sie haben Methoden, mit denen wir auf einfache Art und Weise auf die Daten zugreifen können: * ''getType()'' liefert die Art des Knotens (''object'', ''array'', ''string'', ''number'' oder ''boolean'') * Ist der Knoten ein Objekt (Typ ''object''), so erhält man mittels ''getAttributeValue(String bezeichner)'' das ''JsonElement''-Objekt, das den Wert des Attributs mit dem gegebenen Bezeichner enthält. Falls das Attribut nicht selbst ein Objekt oder Array ist, kann man diesen Wert mittels ''getAsString(String bezeichner'', ''getAsDouble(String bezeichner)'', ''getAsInt(String bezeichner)'' oder ''getAsBoolean(String bezeichner)'' gleich direkt holen. * Ist der Knoten ein Array (Typ ''array''), so erhält man mittels ''getArrayValues()'' ein Java-Array mit ''JsonElement''-Objekten, die die Daten der Elemente im JSon-Array enthalten. * Ist der Knoten ein String-Wert, eine Zahl oder ein boolescher Wert (Typ ''string'' oder ''number'' oder ''boolean''), so erhält man die Daten mittels ''getAsString()'', ''getAsDouble()'', ''getAsInt()'' und ''getAsBoolean()''.