Lekce 4 - Síť v Javě - Práce s URLConnection
v dnešním Java tutoriálu se zaměříme na další
třídu z balíčku java.net
. Představíme si třídu
URLConnection
a její podtřídy, které pro práci se
sítí využijeme. Vše si pak vyzkoušíme na praktickém
příkladu.
Třída URLConnection
Třída URLConnection
je abstraktní třída,
jejíž podtřídy tvoří spojení mezi uživatelskou aplikací a jakýmkoli
zdrojem na webu. Třídu můžeme použít ke čtení z
jakéhokoli zdroje, na který odkazuje objekt URL a také k
zápisu do něj. Existují hlavně dvě podtřídy, které
rozšiřují třídu URLConnection
.
HttpURLConnection
- Pokud se připojujeme k jakékoli URL, která používá HTTP jako svůj protokol, použijeme tuto podtřídu.JarURLConnection
- Pokud se však pokoušíme navázat připojení k souboru.jar
na webu, použijeme podtříduJarURLConnection
.
Třída URLConnection
nám umožňuje získat informace ze
serveru, zpracovat je a výsledky buď odeslat zpět na server, nebo pouze
zobrazit požadovanou informaci.
Představme si například aplikaci, která od uživatele požaduje název filmu a na oplátku vrací hodnocení filmu nebo všechny odkazy související s ním.
Jakmile je tedy navázáno spojení (vytvořený objekt třídy
URL
) a program Java má objekt URLConnection
, pak jej
lze použít ke čtení nebo zápisu či získávání dalších informací
např. délky obsahu a podobně.
Metody třídy
URLConnection
Než se pustíme do příkladů, popišme si základní metody, které máme k dispozici.
Metody sloužící k úpravě parametrů požadavku:
setAllowUserInteraction(boolean)
- Umožňuje povolit či zakázat uživatelské interakce (parametr nastavíme natrue
, resp.false
).setDoInput(boolean)
- Pokud se má použít připojení URL pro vstup, pak bude hodnota nastavena natrue
(výchozí).setDoOutput(boolean)
- Můžeme také určit, zda se má použít připojení URL pro výstup. Zde je výchozí hodnotafalse
.setIfModifiedSince(long)
- Nastaví hodnotuifModifiedSince
podle tohotoURLConnection
na zadanou hodnotu.setUseCaches(boolean)
- Některé protokoly ukládají dokumenty do mezipaměti. Občas je zapotřebí mezipamět ignorovat (např. tlačítko znovu načíst v prohlížeči), v takovém případě změníme výchozí hodnotuUseCaches
ztrue
nafalse
.setRequestProperty(String, String)
- Tato metoda nastavuje vlastnost obecného požadavku. Pokud vlastnost s klíčem již existuje, přepíše původní hodnotu novou.
Metody pro přístup k polím záhlaví a obsahu po vytvoření připojení ke vzdálenému objektu:
getContent()
- Načte obsah připojení URL.getHeaderField(int)
- Vrátí hodnotu pole n-tého záhlaví. Vrátínull
pokud je polí méně než n+1.getInputStream()
- Vrátí vstupní datový proud, který čte z aktuálně otevřeného připojení.getOutputStream()
- Vrátí výstupní proud, který zapisuje do tohoto připojení.getContentEncoding()
- Vrátí hodnotu kódování obsahu zdroje, na který URL adresa odkazuje, případněnull
, pokud není známo.getContentLength()
- Vrátí délku obsahu zdroje, na který odkazuje URL adresa tohoto připojení. Pokud délka obsahu není známa nebo je větší nežInteger.MAX_VALUE
získáme hodnotu-1
.getContentType()
- Vrátí typ obsahu zdroje, na který URL adresa odkazuje nebonull
, pokud není znám.getDate()
- Získáme datum odeslání zdroje, na který URL adresa odkazuje nebo0
, pokud není známo. Vrácená hodnota je počet milisekund od 1. ledna 1970 GMT.getExpiration()
- Vrátí datum vypršení platnosti zdroje, na který tato URL adresa odkazuje. Jako předchozí metoda vrací počet milisekund od 1. ledna 1970 GMT, případně0
.getLastModified()
- Vrátí datumURLConnection
poslední úpravy zdroje, na který se odkazuje, pokud není známo bude opět vrácena hodnota0
.
Každá z výše uvedených set
metod má
odpovídající get
metodu pro načtení hodnoty parametru nebo
vlastnosti obecného požadavku.
Čtení z URL pomocí
URLConnection
Pro čtení z URL pomocí třídy URLConnection
je potřeba
provést následující kroky:
1. Vytvoříme objekt třídy URL
- viz. článek věnovaný práci s URL:
URL url = new URL("https://...");
2. Vytvoříme objekt URLConnection
- Zavoláme metodu
openConnection()
, která vytvoří objekt
URLConnection
, inicializuje ho a připojí se na toto URL po síti.
Pokud se něco nepovede metoda vyvolá výjimku IOException
:
URLConnection urlConection = url.openConnection();
3. Zobrazíme informaci o obsahu do konzole - Vytvoříme objekt typu
BufferedReader
a InputStream
v jehož parametru na
objekt URLConnection
zavoláme metodu
getInputStream()
:
BufferedReader br = new BufferedReader(new InputStreamReader(urlConection.getInputStream())); // získání vstupního streamu // tisk zdrojového souboru řádek po řádku String s = br.readLine(); while (s != null) { System.out.println(s); s = br.readLine(); }
4. Uzavřeme stream - Po dokončení nesmíme zapomenout zavřít
InputStream
. Na instanci BufferedReader
jednoduše
zavoláme metodu close()
:
br.close();
Použití
třídy URLConnection
pro zobrazení zdrojového kódu webové
stránky
Náš program pro zobrazení webové stránky bude vypadat následovně:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; public class URLConectionDemo { public static void main(String[] args) { try { URL url = new URL("https://www.itnetwork.cz/java/sit"); // vytvoří spojení na server URLConnection urlConection = url.openConnection(); System.out.println("Typ obsahu zdroje: " + urlConection.getContentType()); System.out.println("Kódování obsahu zdroje " + urlConection.getContentEncoding()); System.out.println("Délku obsahu zdroje " + urlConection.getContentLength()); System.out.println("Datum odeslání zdroje " + urlConection.getDate()); System.out.println("Datum vypršení platnosti zdroje " + urlConection.getExpiration()); System.out.println("Datum URLConnection poslední úpravy zdroje " + urlConection.getLastModified()); System.out.println(); int i = 0; while (urlConection.getHeaderField(i) != null) { System.out.printf("Hodnota pole %s záhlaví %s \n", i, urlConection.getHeaderField(i)); i++; } // získání vstupního streamu (vstupní datový proud) - používá se ke čtení vrácených dat BufferedReader br = new BufferedReader(new InputStreamReader(urlConection.getInputStream())); System.out.println("Úplný zdrojový kód adresy URL je:"); System.out.println("---------------------------------"); // tisk zdrojového souboru řádek po řádku String s = br.readLine(); while (s != null) { System.out.println(s); s = br.readLine(); } br.close(); } catch(Exception e) { System.out.println(e); } } }
Pokud kód nyní spustíme, vypíše následující údaje:
Konzolová aplikace
Typ obsahu zdroje: text/html
Kódování obsahu zdroje null
Délku obsahu zdroje -1
Datum odeslání zdroje 1662301433000
Datum vypršení platnosti zdroje 375007920000
Datum URLConnection poslední úpravy zdroje 0
Hodnota pole 0 záhlaví HTTP/1.1 200 OK
Hodnota pole 1 záhlaví Sun, 04 Sep 2022 14:23:53 GMT
Hodnota pole 2 záhlaví text/html
Hodnota pole 3 záhlaví chunked
Hodnota pole 4 záhlaví keep-alive
Hodnota pole 5 záhlaví Thu, 19 Nov 1981 08:52:00 GMT
Hodnota pole 6 záhlaví no-store, no-cache, must-revalidate
Hodnota pole 7 záhlaví no-cache
Hodnota pole 8 záhlaví PHPSESSID=tplbphmh8sdf80mc3i8a924318; path=/; HttpOnly
Hodnota pole 9 záhlaví DYNAMIC
Hodnota pole 10 záhlaví {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=1scb9G4wzyQJQbiiQZEmI7lePMxUSSmVWekBYrnrKqCpGFqy5OrJDOR2RYFuDh70TYx%2BasKNItyRqTXVzdK0mVfoXhX8WCft9vIEEWBjPiScAI3VWb0xre1RCJWBoElQ16XO"}],"group":"cf-nel","max_age":604800}
Hodnota pole 11 záhlaví {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Hodnota pole 12 záhlaví cloudflare
Hodnota pole 13 záhlaví 745762b3df33b347-PRG
Hodnota pole 14 záhlaví h3=":443"; ma=86400, h3-29=":443"; ma=86400
Úplný zdrojový kód adresy URL je:
---------------------------------
// zde bude zdrojový kód stránky...
Program dělá v podstatě to samé co dělal program, jenž
jsme si ukázali v článku Síť v
Javě - Práce s URL, který demonstroval čtení přímo z URL za pomocí
metody openStream()
. Avšak čtení z URL pomocí třídy
URLConnection
je výhodnější, protože objekt této třídy
můžeme současně použít v jiném úkolu, třeba pro zápis.
Zápis do URL pomocí
URLConnection
Mnoho HTML dokumentů obsahuje formuláře, tj. textové položky a jiné GUI objekty, kterými se zadávají data pro server. Po zadání prohlížeč předá data serveru. Na druhém konci sítě speciální programy data zpracují a pošlou zpět odpověď, většinou ve tvaru HTML dokumentu.
Aby Java program mohl interagovat s procesem na straně serveru, musí být schopen zapisovat na URL, a tak poskytovat data serveru. Toho docílíme pomocí následujících kroků:
1. Vytvoříme objekt URL
:
URL url = new URL("http//...");
2. Dále Vytvoříme objekt URLConnection
:
URLConnection conection = url.openConnection();
3. Z otevřeného spojení tentokrát vezmeme výstupní stream, který je připojen ke standardnímu vstupnímu streamu programu na serveru:
PrintStream outStream = new PrintStream(connection.getOutputStream());
4. Zapisovat pak data do streamu můžeme standardními metodami, např.:
outStream.println();
5. Nakonec stream opět zavřeme:
outStream.close();
Vidíme, že postup je obdobný, jako v případě čtení dat, které jsme si ukázali výše.
Jak už bylo zmíněno výše, pokud se připojujeme k jakékoli
URL, která používá HTTP protokol, využívá se třída
HttpURLConnection
. Tuto třídu včetně příkladů použití si
popíšeme v některé z dalších lekcí.
V příští lekci, Síť v Javě - Práce s HttpURLConnection - Požadavek GET, si popíšeme třídu
HttpURLConnection
a metody, které pro práci se sítí poskytuje.
Ukážeme si také, jak ji použít v praxi ve spojení s HTTP požadavkem
GET.