Síťová rozhraní
Síťové rozhraní je v Javě reprezentováno třídou NetworkInterface z balíku java.net. Můžeme ho získat statickými továrními metodami getByInetAddress(InetAddress addr) a getByName(String name). Další možností je metoda getNetworkInterfaces(), která vrátí enumerátor Enumeration<NetworkInterface> pro všechna síťová rozhraní.
Třída NetworkInterface dále poskytuje metody pro získání informací o daném rozhraní:
- String getName() – Vrátí jméno síťového rozhraní.
- String getDisplayName() – Vrátí popis síťového rozhraní.
- Enumeration<InetAddress> getInetAddresses() – Vrátí výčet adres příslušících tomuto rozhraní.
Výpis všech síťových rozhraní
for(Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
interfaces.hasMoreElements();) {
NetworkInterface intfc = interfaces.nextElement();
System.out.print(intfc.getName() + "\t");
for(Enumeration<InetAddress> addresses = intfc.getInetAddresses();
addresses.hasMoreElements();) {
InetAddress addr = addresses.nextElement();
System.out.print(addr + "\t");
}
System.out.println();
}
V případě chyby může metoda getNetworkInterfaces() vyvolat výjimku java.io.SocketException.
HTTP protokol
API obsažené v balíku java.net také poskytuje poměrně jednoduchý mechanismus pro práci s HTTP protokolem. Základem je třída URLConnection, která vytváří připojení na zadané URL. V balíku java.net má dvě podtřídy – JarURLConnection pro stahování JAR archivů a HttpURLConnection pro práci s HTTP protokolem.
Připojení k serveru
Pro připojení na zadané URL slouží metoda openConnection() třídy java.net.URL. Podle použitého protokolu vrátí instanci některé z podtříd URLConnection. V našem případě to tedy bude objekt typu HttpURLConnection.
Objekt získaný touto metodou je připravený ke stažení dokumentu na zadaném URL.
Přesměrování
Třída HttpURLConnection umí zpracovat i přesměrování. Může se však stát, že přesměrování potřebujeme vypnout. K tomu slouží statická metoda HttpURLConnection.setFollowRedirects(boolean set). Pokud je hodnota parametru set false, přesměrování neproběhne.
Čtení hlaviček
Pro čtení HTTP hlaviček odpovědi slouží tyto metody třídy URLConnection:
- String getHeaderFieldKey(int n) – Vrátí jméno n-té hlavičky.
- String getHeaderField(String name) – Vrátí hodnotu hlavičky pojmenované name.
- String getHeaderField(int n) – Vrátí hodnotu n-té hlavičky.
- int getHeaderFieldInt(String name, int Default) – Vrátí hodnotu hlavičky pojmenované name jako datum. Datum je určeno počtem milisekund od 1. ledna roku 1970. Jestliže hlavička chybí nebo její hodnotu nelze načíst, bude vrácena Default.
- int getHeaderFieldInt(String name, int Default) – Vrátí celočíselnou hodnotu hlavičky name. Opět jako v předchozím případě platí, že pokud hodnotu nelze získat, je vrácen parametr Default.
- Map<String,List<String>> getHeaderFields() – Vrátí všechny hlavičky jako mapu. Klíči jsou názvy hlaviček, jako prvky jsou uloženy seznamy všech jejich hodnot.
Čtení obsahu odpovědi
K přečtení odpovědi slouží metoda getInputStream() třídy URLConnection. Do tohoto vstupního proudu je postupně odesílána odpověď. Jakmile jsou všechna data přečtena, proud se ukončí.
Příklad HTTP spojení
Tento jednoduchý příklad načte úvodní stránku Rootu a vypíše ji na konzoli. Může vyvolat výjimky java.net.MalformedURLException nebo java.io.IOException.
URL url = new URL("http://www.root.cz");
HttpURLConnection http = (HttpURLConnection)url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(http.getInputStream()));
String s;
while((s = reader.readLine()) != null) {
System.out.println(s);
}
reader.close();
Další příklad vypíše všechny hlavičky i s jejich hodnotami:
URL url = new URL("http://www.root.cz");
HttpURLConnection http = (HttpURLConnection)url.openConnection();
Map<String,List<String>> headers = http.getHeaderFields();
for(String key: headers.keySet()) {
for(String value: headers.get(key)) {
System.out.println(key + ": " + value);
}
}
Na této ukázce si lze povšimnout zajímavé věci: hlavičky „null: HTTP/1.1 200 OK“. V žádném případě se najedná o hlavičku, nýbrž o první řádek odpovědi udávající výsledek HTTP požadavku.
Znakové sady pomocí java.nio.charset.Charset
Balík java.nio.charset má na starosti znakové sady v New I/O. Umožňuje převádět obsah bajtových bufferů na řetězce a naopak vytvářet ze znakových bufferů bajtové. Nyní si popíšeme jednu z jeho pěti tříd – třídu Charset představující znakovou sadu.
java.nio.charset.Charset
Třída Charset reprezentuje znakovou sadu. K získání její instance a tedy i znakové sady je možno použít tyto dvě statické tovární metody:
- static Charset defaultCharset() – Vrátí výchozí znakovou sadu.
- static Charset forName(String charsetName) – Vytvoří znakovou sadu podle zadaného názvu.
Třetí možností, jak objekt typu Charset získat, je metoda static SortedMap<String,Charset> availableCharsets(). Ta vrátí mapu obsahující všechny dostupné znakové sady. Jako klíče jsou použity jejich názvy.
Pokud potřebujeme zjistit, zda je určitá znaková sada podporovaná, použijeme metodu static boolean isSupported(String charsetName).
Nyní se pojďme podívat na užitečné metody poskytované třídou Charset:
- Set<String> aliases() – Vrátí seznam (resp. množinu) všech aliasů této znakové sady.
- CharBuffer decode(ByteBuffer bb) – Převede obsah zadaného bajtového bufferu na znakový buffer.
- ByteBuffer encode(CharBuffer cb) – Vrátí nový bajtový buffer obsahující znaky ze zadaného znakového bufferu.
- ByteBuffer encode(String str) – Vrátí nový bajtový buffer obsahující zadaný řetězec.
- CharsetDecoder newDecoder() – Vytvoří nový dekodér této znakové sady.
- CharsetDecoder newEncoder() – Vytvoří kodér pro znakovou sadu.
Pokud máte zájem dozvědět se více o (de)kodérech, nahlédněte do dokumentace tříd CharsetDecoder a CharsetEncoder.
Příklad práce se znakovými sadami
Následující příklad ukazuje, jak lze pracovat s třídou Charset. Jako parametr konzole zadáme znakovou sadu a program vypíše všechny její aliasy (ostatní názvy). Pokud parametr nezadáme nebo znaková sada neexistuje, aplikace upozorní příslušným chybovým hlášením a vytiskne na konzoli seznam dostupných kódování.
import java.nio.charset.*;
import java.util.*;
public class CharsetAliases {
public static void main(String[] args) {
if(args.length < 1) {
System.out.println("Použití: java CharsetAliases znaková_sada");
available();
return;
}
String charsetName = args[0];
if(!Charset.isSupported(charsetName)) {
System.out.println("Nepodporovaná znaková sada: " + charsetName);
available();
return;
}
Charset charset = Charset.forName(charsetName);
Set<String> aliases = charset.aliases();
System.out.println("Aliasy znakové sady " + charsetName + ":");
for(String alias: aliases) {
System.out.println(alias);
}
System.out.println("Celkem aliasů: " + aliases.size());
}
private static void available() {
System.out.println("\nDostupné znakové sady:");
Map<String,Charset> charsets = Charset.availableCharsets();
for(String name: charsets.keySet()) {
System.out.println(name);
}
System.out.println("Celkem znakových sad: " + charsets.keySet().size());
}
}
Závěr
Dnes jsme se dostali až na konec celého osmidílného seriálu. Ukázali jsme si, jakým způsobem získat seznam síťových rozhraní, jednoduchou práci s HTTP protokolem a základ znakových sad v balíku java.nio.charset.
Nyní mi už zbývá jen popřát vám hodně úspěchů při síťování i jiném programování v Javě. Zroveň věřím, že se vám seriál líbil a měl pro vás nějaký přínos. Pokud budete mít někdy k síťování v Javě jakékoliv dotazy, můžete se obrátit na email wantox@gmail.com, ochotně vám odpovím.