In questa breve serie di mini-tutorials vorrei ilustrare le tecniche base a disposizione del linguaggio java per interagire con un server HTTP usando le API del package standard java.net.
In questa prima parte vedremo come instaurare inviare una richiesta ad un server HTTP e come leggere l”intestazione di risposta.
Introduzione al protocollo HTTP
HTTP (acronimo di Hyper Text Transfer Protocol), inventato alla fine degli anni ”80 da Tim Berners-Lee al CERN di Ginevra è il protocollo di trasferimento più usato nel World-Wide Web.
Si basa sul concetto di Request/Reply, cioè il client (solitamente un browser ) invia un pacchetto di richiesta (Request) ad un server HTTP, il quale risponde con un pacchetto di risposta (Reply). I pacchetti dirichiesta e di risposta hanno struttura simile che è:
|
Status-Line |
| Header |
|
Body |
| Valori Request: Status-Line:GETPOSTHEADERPUT
DELETE TRACE CONNECT Header: Informazioni sul pacchetto Body: corpo della richiesta |
Valori Reply: Status-Line: codice di tre cifre con valori:1xx : Informational2xx: Success3xx: Redirection4xx: Client error 5xx: Server error Body: contenuto della risposta |
Il campo header sia nei pacchetti di richiesta che in quelli di riposta può contenere informazioni estremamente utili per capire la natura del contenuto del pacchetto trasmesso, l” identità del cliente quella del server, etc. I valori degli header sono espressi in forma “chiave=valore”.
La semplice classe Java riportata in questo tutorial non fa altro che mostrare come sia possibile inoltrare una richiesta ad un server HTTP ed analizzare l” header del pacchetto con poche righe di codice e le classi dell ”API standard del JDK di Sun presenti fin dalla versione 1.0.
HTTPHeaderInfo
| public class HttpHeaderInfo { public HttpHeaderInfo() {try {// Crea un nuovo oggetto URL con l”indirizzo del server HTTPURL url = new URL(” http://www.brainspace.it “);// Crea una nuova connessione all”URL inviando
// una richiesta di connessione al server URLConnection connessione = url.openConnection(); System.out.println(“Informazioni sull”Header Http: “); // Legge tutti i campi dell”header Http for (int n=0; ; n++) { // Legge la chiave campo n String chiave_header = connessione.getHeaderFieldKey(n); // Legge il valore del campo n String valore_chiave_attuale = connessione.getHeaderField(n); // Se la sia la chiave che il campo sono nulli… if (chiave_header == null && valore_chiave_attuale == null) { System.out.println(“—”); // …allora non ci sono più campi da esaminare // e l”analisi dell”header termina break; } // se la chiave del campo e” nulla ma il valore esiste… if (chiave_header == null) { // …allora il valore e” la versione http chiave_header = “Version”; } System.out.println(chiave_header + ” = ” + valore_chiave_attuale); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new HttpHeaderInfo(); } } |
Nel codice vengono utilizzate due classi del package strandard che sono java.net.URL e java.net.URLConnection. La classe URL trasforma la stringa passata al costruttore in un indirizzo URL (Uniform Resource Locator) che rappresenta l”oggetto che si desidera richiedere al server HTTP. Una volta creato l”URL si usa il metodo openConnection() della classe URL per aprire una connessione ed inviare una richiesta al server HTTP per la risorsa specificata dall”URL ed attende una risposta da parte del server HTTP. Una volta ricevuta la risposta si procede ad analizzare tutti i capi dell ”intestazione del pacchetto di risposta ricevuto. In modo più dettagliato le operazioni svolte sono:
Linea 6: URL url = new URL(” http://www.brainspace.it “);
Linea 9: URLConnection connessione = url.openConnection();
Per prima cosa alla linea 6 si crea l” oggetto URL corrispondente all ”indirizzo http://www.brainspace.it , in caso l” URL specificato sia malformato in questo punto verrà sollevata una eccezione di tipo java.net.MalformedURLException. La linea 9 apre la connessione con il server, invia un pacchetto di richiesta per la risorsa specificata (cioè pa pagina indice del sito brainspace.it) ed attende la risposta. Il metodo può sollevare una eccezione IO (java.io.IOException) in caso di problemi .Il ciclo principale:
Linea 14: for (int n=0; ; n++) {
Linea 16: String chiave_header = connessione.getHeaderFieldKey(n);
Linea 18: String valore_chiave_attuale = connessione.getHeaderField(n);
Linea 21: if (chiave_header == null && valore_chiave_attuale == null) {
Linea 22: System.out.println(“—”);
Linea 25: break;
Linea 26: }
Linea 29: if (chiave_header == null) {
Linea 31: chiave_header = “Version”;
Linea 32: }
Linea 33: System.out.println(chiave_header + ” = ” + valore_chiave_attuale);
Linea 34: }
legge tutte le chiavi ed i loro valori corrispondenti per mezzo dei metodi getHeaderFieldKey(index) e getHeaderField(index) fino a quando sia la chiave che il suo valore associato sono nulli ( if (chiave_header == null && valore_chiave_attuale == null)… ); in tal caso il ciclo termina in quanto entrambi i valori nulli indicano che sono state analizzate tutte le chiavi del campo header. Nel caso il campo chiave sia nullo ma il suo valore non lo sia significa che il valore è la versione del protocollo HTTP di risposta e viene impostato in nome del campo manualmente. Si può notare che in nessun luogo vengono invocati metodi di disconnessione. Questo è dovuto alla natura del protocollo HTTP detto stateless (privo di stato) in cui generalmente la connessione viene chiusa in modo automatico al termine di ciascuna risposta da parte del server.
Conclusione
Pretendere di affrontare un argomento vasto come il protocollo HTTP in poche righe non è assolutamente cosa fattibile, però lo scopo di questo primo tutorial era mostrare con quanta semplicità è possibile interagire con un server HTTP tramite poche righe di codice JAVA. L”output che si ottiene dall”esecuzione della classe precedente è il seguente:
Informazioni sull’Header Http:
Version = HTTP/1.1 200 OK
Date = Fri, 30 Mar 2007 08:39:15 GMT
Server = Apache/2.0.52 (CentOS)
X-Powered-By = PHP/5.0.4
Set-Cookie = dab600f341a90efac62d15068358cc48=b57a30c4b7ad3eb38ae50a1bf71da4d0; path=/
Expires = Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control = no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma = no-cache
Content-Length = 1063
Keep-Alive = timeout=15, max=100
Connection = Keep-Alive
Content-Type = text/html
—
mentre se si cambia l”indirizzo dalla pagina PHP http://www.brainspace.it con l”indirizzo http://www.brainspace.it/downloads/SimpleDownloader.zip che fa riferimento ad un archivio in formato ZIP, i campi che costituiscono l”header del pacchetto di risposta cambiano in questo modo:
Informazioni sull”Header Http:
Version = HTTP/1.1 200 OK
Date = Wed, 11 May 2005 14:22:20 GMT
Server = Apache
Last-Modified = Wed, 11 May 2005 14:21:44 GMT
ETag = “43bc61e-14a22-428214f8″
Accept-Ranges = bytes
Content-Length = 84514
Connection = close
Content-Type = application/zip
—
Può essere interessante provare ad inserire risorse di vari tipi come indirizzi di input per verificare i cambiamenti dell”header, in attesa del secondo tutorial della serie.
Intanto, per chi fosse interessato al funzionamento ed alla storia del protocollo HTTP segnalo alcuni links nella sezione “Risorse” del tutorial:
Il sorgente contenete la classe costruita in questo tutorial è liberamente scaricabile: [Download not found]
Per quanti volessero approfondire l” argomento HTTP è utile consultare questi siti:
Informazioni sull”HTTP in Wikipedia: Pagina su Wikipedia dedicata al protocollo HTTP
RFC 1945: Specifiche della versione 1.0 del protocollo HTTP
RFC 2616: Specifiche della versione 1.1 del protocollo HTTP



marzo 30th, 2010 at 14:17
[...] “Java ed il protocollo HTTP (Prima Parte)” abbiamo visto come richiedere una connessione ad un server HTTP, cosa interessante, ma anche [...]