|
Generic
Connection Framework
Nell'articolo pubblicato su MokaByte di febbraio, riguardante
la configurazione CLDC, abbiamo già accennato
alla gestione delle connessioni in J2ME. Abbiamo visto
che, data la varietà di dispositivi che possono
supportare J2ME e le differenti tipologie di connessione
che questi possono avere (porta seriale, USB, rete telefonica
cellulare a commutazione di pacchetto o a commutazione
di circuito, porta infrarossi, blutooth, ecc.), l'implementazione
dei "meccanismi" di comunicazione non viene
effettuata a livello di configurazione ma viene lasciata
ai profili proprio perché più "legati"
alle piattaforme host. Il MIDP si occupa quindi dell'implementazione
del cosiddetto Generic Connection Framework.

Figura
1 - Gerarchia delle interfacce di connessione (MIDP).
Si
tratta di un insieme di interfacce (le stesse previste
dalla configurazione CLDC, più l'HttpConnection
introdotta dal MIDP) che rappresentano diversi gradi
di astrazione dal particolare tipo di connessione (o
di protocollo).
La radice della gerarchia, Connection, costituisce la
rappresentazione "più astratta" di
connessione stabilendo semplicemente che qualunque tipo
di connessione può essere aperta (open(..)) o
chiusa con il metodo:
public
void close()
(in
realtà la connessione viene aperta utilizzando
il metodo statico open della classe Connector che vedremo
tra breve). Le interfacce InputConnection e OutputConnection
sono un'estensione di Connection e rappresentano rispettivamente
un flusso in ingresso e un flusso in uscita da un dispositivo
di comunicazione. Queste interfacce forniscono i metodi
per l'apertura dei flussi di ingresso e uscita dalla
connessione:
public
InputStream openInputStream()
public DataInputStream openDataInputStream()
per
quanto riguarda una connessione in ingresso (InputConnection),
mentre per quelle in uscita (OutputConnection) sono
previsti metodi analoghi per l'apertura di stream in
scrittura:
public
OutputStream openOutputStream()
public DataOutputStream openDataOutputStream()
La
combinazione di InputConnection e OutputConnection "genera"
una nuova interfaccia, StreamConnection, provvista di
flussi bidirezionali (input e output stream).
StreamConnection, infatti, non possiede alcun metodo,
se non quelli ereditati dalle sue "superinterfacce".
ContentConnection estende direttamente StreamConnection
e fornisce tre metodi addizionali:
public
String getType()
public String getEncoding()
public long getLength()
per
la gestione dei dati (e dei tipi MIME) inviati e ricevuti
( ad esempio se il protocollo utilizzato è l'
Http essi ritornano rispettivamente il Content-Type,
il Content-Encoding e il Content-Length).
L'interfaccia HttpConnection infine fornisce, come vedremo
più avanti, un insieme di metodi per il supporto
del protocollo Http.
StreamConnectionNotifier possiede un unico metodo:
public
StreamConnection acceptAndOpen()
questo
restituisce uno StreamConnection, che rappresenta la
"versione server" di un socket per la comunicazione
con un client (è simile ad un ServerSocket ).
L'interfaccia DatagramConnection, permette la creazione
di datagram per la comunicazione di tipo UDP (User Datagram
Protocol). Analizzeremo il supporto alle connessioni
di tipo datagram del MIDP più avanti in questo
articolo, passando ora ad occuparci del procedimento
di apertura di una connessione.
Apertura
di una connessione: la classe Connector
Nel package javax.microedition.io, che è il "contenitore"
di tutti gli strumenti di connessione troviamo, oltre
alle già citate interfacce anche una, peraltro
unica, classe "concreta": Connector. Tale
classe possiede sette metodi statici che permettono
l'apertura effettiva della connessione sulla quale sarà
poi possibile collegare gli stream di I/O, per le operazioni
di lettura e/o scrittura.
Indipendentemente dal tipo di connessione che si intende
utilizzare occorrerà richiamare il metodo (statico)
open per poterla utilizzare in lettura e/o scrittura.
Il metodo open prevede tre firme differenti:
public
static Connection open(String connectionString)
public static Connection open(String connectionString,
int mode)
public static Connection open(String connectionString,
int mode, boolean timeouts)
Il
parametro connectionString rappresenta la stringa di
connessione ed ha un formato particolare che tra breve
illustreremo, il valore intero mode indica la modalità
di apertura della connessione e può assumere
uno dei seguenti valori interi (variabili intere statiche
della classe Connector):
- READ
- apertura in sola lettura;
- WRITE
- apertura in sola scrittura;
- READ_WRITE
- apertura sia in lettura che in scrittura (valore
di default);
Il
booleano timeout, il cui valore di default è
false, se impostato a true indica che il metodo può
generare eccezioni dovute al timeout del tipo InterruptedIOException.
Per quanto riguarda la connectionString, essa ha una
generica forma del tipo:
{protocol}:
[{target}] [{parameters}]
- protocol
- indica il tipo di connessione che si vuole attivare
(ad esempio: I/O su file, porta seriale, datagram,
socket, Http)
- target
- dipende da protocol e, può essere il nome
di un file, di una porta seriale, il nome di una porta
di comunicazione o il nome di un host.
- parameters
- sono parametri aggiuntivi (opzionali) che forniscono
informazioni funzionali per un dato tipo di connessione.
Ad esempio la velocità, i bit di start e stop
e la parità di una connessione seriale.
Alcuni
esempi di stringhe di connessione possono essere:
Connection
fileConn = Connector.open("file:/myFile.txt");
Connection serialConn = Connector.open("comm.:0;baudrate=9600");
Connection socketConn = Connector.open("socket://193.0.0.1");
Connection datagramConn = Connector.open("datagram://193.0.0.1:9000");
Connection httpConn = Connector.open("http://www.mokabyte.it");
Per
l'apertura di una connessione si può, in alternativa
all'utilizzo del metodo open, ricorrere ai metodi:
public
static DataInputStream openDataInputStream(String connectionString)
public static InputStream openInputStream(String connectionString)
public static DataOutputStream openDataOutputStream(String
connectionString)
public static OutputStream openOutputStream(String connectionString)
che
ritornano stream di input/output associati alla connessione
indicata da connectionString. Essi permettono di ottenere
immediatamente uno stream di I/O per una data connessione,
ad esempio, l'istruzione:
DataInputStream
in = Connector.openDataInputStream("socket://193.0.0.1:8080");
è
equivalente al seguente codice:
InputConnection
inConnection =(InputConnection ) Connector.open("socket://193.0.0.1:8080");
DataInputStream in = inConnection. OpenDataInputStream();
Le operazioni di apertura di una connessione possono
generare eccezioni; in particolare se la connectionString
passata ad un "metodo di apertura" non è
ben formata si avrà una IllegalArgumentException,
mentre se essa indica un tipo di protocollo non supportato
verrà generata una ConnectionNotFoundException.
Una eccezione di tipo IOException, infine, sta ad indicare
che si è verificato un qualche errore di I/O.
Connessioni
di tipo datagram
La comunicazione datagram si basa sull'invio in rete
di "messaggi" (i datagram, appunto), senza
garanzie sull'integrità dei dati giunti al destinatario,
sull'istante di arrivo e neppure sulla consegna dei
dati stessi. Si tratta di una tecnica di comunicazione
di tipo non-connesso, nel senso che non esiste tra mittente
e destinatario del messaggio un percorso dedicato (neppure
logico): i dati inviati contengono al loro interno le
informazioni necessarie per individuare il destinatario
(indirizzo IP e porta della macchina di destinazione).
Questo tipo di comunicazione si adatta molto bene a
reti di comunicazione wireless a commutazione di pacchetto,
mentre può non essere supportata da reti a commutazione
di circuito che si basano su stream (esiste un percorso
diretto tra mittente e destinatario attraverso il quale
vengono inviati i dati).
L'utilizzo
delle connessioni di tipo datagram impone, solitamente,
questi sei passi:
- il
mittente stabilisce una connessione datagram
- il
mittente costruisce un oggetto datagram da inviare
contenente indirizzo e porta del destinatario e naturalmente
le informazioni da inviare
- invio
del datagram costruito attraverso la connessione aperta
- costruzione
di un oggetto datagram (vuoto) per la ricezione di
eventuali dati in risposta
- attesa
di una eventuale risposta. I dati ricevuti vengono
scritti nel datagram vuoto pre-allocato
- chiude
la connessione datagram aperta
Le
operazioni appena esposte possono essere eseguite, nel
MIDP, utilizzando le classi Datagram e DatagramConnection:
la prima rappresenta "l'unità informativa"
cioè il datagram, l'altra la connessione datagram
vera e propria.
Per l'apertura della connessione datagram si utilizzano
il metodo open, visto in precedenza, nel seguente modo:
DatagramConnection
datagramConn = (DatagramConnection)
Connector.open("datagram://193.0.0.1:8000);
L'omissione
dell'indirizzo nella stringa di connessione permette
l'apertura di connessioni in modalità server:
DatagramConnection
datagramConn = (DatagramConnection)
Connector.open("datagram://:8000);
Che
è equivalente a:
DatagramConnection
datagramConn = (DatagramConnection)
Connector.open("datagram://localhost:8000);
Le
connessioni aperte in modalità server possono
essere utilizzate sia per l'invio sia per la ricezione
dei datagram, mentre con le connessioni client permettono
solo l'invio.
Per
la manipolazione dei datagram e del loro contenuto l'omonima
classe prevede un insieme di metodi che permetto l'accesso
al "campo" indirizzo e al "campo"
dati del datagram stesso:
public
String getAddress()
public void setAddress(String address)
public void setAddress(Datagram reference)
il
primo metodo ritorna l'indirizzo inserito in un oggetto
datagram, gli altri due ne permettono il settaggio passando
rispettivamente una stringa corrispondente all'indirizzo
stesso o un riferimento ad un datagram (in questo caso
l'indirizzo sarà uguale a quello del datagram
di riferimento).
public
int getLength()
public void setLength(int length)
public int getOffset()
public void setData(byte[] buffer, int offset, int length)
public byte[] getData()
public void reset()
permettono invece la manipolazione dei dati e degli
attributi ad essi inerenti.
Il primo metodo, getLength, fornisce informazioni sul
lunghezza (in byte) del buffer contenente i dati mentre
utilizzando il secondo è possibile impostarla.
getOffset permette di ottenere il posizionamento dell'offeset
(puntatore in scrittura) all'interno del campo dati.
Il metodo setData, consente la scrittura dei dati all'interno
del datagram: i dati da scrivere sono contenuti in un
array di byte (buffer) il metodo provvederà alla
loro scrittura dentro il datagram a partire dalla posizione
indicata da offset e per un numero totale di byte stabiliti
con la variabile length. Per l'operazione contraria,
cioè la lettura, è previsto il metodo
getData, che ritorna appunto un array di byte che rappresentano
il "campo" dati del datagram.
reset, infine, permette di "ripulire" il datagram
riportando il puntatore ai dati scritti/letti nella
posizione iniziale.
I metodi finquì visti permettono di operare sull'oggetto
datagram senza però occuparsi né della
loro creazione né della loro trasmissione/ricezione:
la classe DatagramConnection gestisce proprio questi
aspetti.
Attraverso il metodo newDatagram è possibile
creare un oggetto datagram.
public
Datagram newDatagram(int size)
public Datagram newDatagram(int size, String address)
public Datagram newDatagram(byte[] buf, int size)
public Datagram newDatagram(byte[] buf, int size, String
addr)
Le
differenti firme di questo metodo permettono la creazione
di nuovo datagram "sempre più specifici":
nel primo caso viene creato un nuovo generico datagram
specificando solo la dimensione (lunghezza dei dati
che può contenere), il secondo metodo permette
di specificare anche l'indirizzo di destinazione, il
terzo crea un datagram di dimensioni prestabilite (size)
nel cui campo dati sono state inserite le informazioni
contenute in buffer, l'ultimo infine permette la creazione
di un datagram "pronto per essere inviato",
cioè con dati, dimensione e indirizzo del destinatario
settati.
Infine,
public
void send(Datagram datagram)
public void receive(Datagram datagram)
si
occupano dell'invio e della ricezione dei datagram,
mentre
public
int getNominalLength()
public int getMaximumLength()
forniscono
rispettivamente la dimensione nominale e la massima
dimensione consentita di un datagram. Quello che segue
è un esempio di come può essere impostata
la connessione datagram nel MIDP:
import
java.io.*;
import javax.microedition.*;
...
...
String destAddress = "datagram://193.0.0.1:8080";
DatagramConnection datagramConn;
String message;
try {
// Apre la connessione datagram in modalità
// server(invio/ricezione)
sulla porta 8000
datagramConn = (DatagramConnection)
Connector.open("datagram://:8000);
//
Viene impostato il messaggio da inviare
message=......
// Il messaggio viene convertito in array
di byte
byte data[] = message.getBytes();
// Viene settata la dimensione del datagram
// (è la dimensione dei dati da inviare)
int size = data.length;
// Crea il datagram contenente il messaggio
da
// inviare a destAddress
Datagram datagramSend;
datagramSend = datagramConn.newDatagram(data,
size, destAddress);
//Invia il datagram
DatagramConn.send(datagramSend );
//Ricava la dimensione massima di un datagram
int maxLength = datagramConn.getMaximumLength();
//Crea un datagram vuoto per i dati da ricevere
Datagram datagramReceive = datagramConn.newDatagram(maxLength);
//Resta in attesa della ricezione di un
datagram
DatagramConn.receive(datagramReceive );
//Legge i dati contenuti nel datagram ricevuto
byte receivedData[] = datagramReceive.getData();
//Utilizza i dati ricevuti
...
...
}
catch(Exception e) {
//Gestisce l'eccezione
}
Connessioni
di tipo socket
La
comunicazione con l'utilizzo di socket del MIDP è
praticamente identica a quella, "classica",
a cui siamo abituati lavorando con la versione Standard
di java. Tale comunicazione può essere suddivisa
in quattro fasi:
- il
client apre una connessione (socket) con un server
remoto o con un altro dispositivo wireless;
- gli
stream di input/output devono essere collegati alla
connessione socket aperta;
- una
volta aperti gli stream è possibile inviare
dati al server (outputstream) e da questo riceverli
(inputstream);
- al
termine delle operazioni di lettura/scrittura occorre
chiudere la connessione e gli stream di I/O;
Un
esempio di utilizzo della classe Connector e dell'apertura
delle connessione di tipo Socket può essere:
import
java.io.*;
import javax.microedition.*;
...
...
String connectionString = "socket://193.0.0.1:8080";
DataInputStream
dis = null;
DataOutputStream dos = null;
StreamConnection sc = null;
...
...
try {
// Apre la connessione come specificato
da connectionString
// Viene restituita una
// StreamConnection alla quale vengono collegati
gli stream
// di input/output (dis/dos)
sc = (StreamConnection) Connector.open(connectionString);
dis = sc.openDataInputStream();
dos = sc.openDataOutputStream();
...
...
// Operazioni di lettura e scrittura sugli
stream di
// input/output dis/dos.
...
dis.close();
dos.close();
sc.close();
}
catch (IOException e) {
// gestisce l'eccezione di I/O
}
Connessioni
Http
L'Http (HyperText Transport Protocol) è un protocollo
di livello applicazione (modello OSI), molto diffuso,
utilizzato per le comunicazioni con web server, sul
quale si basa tutto il "mondo" WWW (World
Wide Web), Sebbene sia, comunque possibile accedere
ad un web server utilizzando i socket, in MIDP esiste
una apposita classe che implementa il protocollo Http
e ne favoriscono la gestione (vedremo, ad esempio come,
con appositi metodi si può facilmente accedere
ai vari campi dell'header del messaggio Http). I vantaggi
derivanti dal supporto Http, non riguardano solo la
maggiore "facilità di gestione" delle
richieste WWW, occorre infatti tener presente che mentre
alcuni dispositivi MIDP non implementano comunicazioni
di tipo socket o datagram praticamente tutti supportano
l'Http. Inoltre, mentre socket e datagram sono comunque
vincolati dal tipo di rete (commutazione di circuito
o di pacchetto) le connessioni Http sono, dal punto
di vista del programmatore, indipendenti dalla rete
sottostante, questo facilita l'utilizzo delle applicazioni
su reti wireless di tipo diverso. Non va dimenticato
inoltre che l'Http ben si presta ad essere utilizzato
in combinazione con l'Xml (eXtensible Markup Language)
( ..... SOAP).
HttpConnection rappresenta l'implementazione del protocollo
Http (Versione 1.1) nel MIDP.
Come già accennato essa permette una facile gestione
delle operazioni previste dal protocollo.
Come per ogni altro tipo di connessione, anche quella
Http, viene attivata, nel MIDP, con il metodo open nella
seguente forma:
HttpConnection
httpConn = (HttpConnection)
Connector.open("http://www.mokabyte.it");
L'implementazione
dell'Http del MIDP supporta tre tipi di richieste: GET,
POST e HEAD.
Il valore di default è GET, gli altri tipi di
richeste possono essere impostate tramite il metodo:
public
void setRequestMethod(String method)
dove
method può assumere appunto i valori POST e HEAD
e naturalmente GET.
Il metodo:
public
void setRequestProperty(String key, String value)
serve
per poter impostare i campi dell'header Http relativi
alla richiesta (ecco alcuni esempi di tali campi:
http.setRequestProperty("User-Agent","Profile/MIDP-1.0
Configuration/CLDC-1.0");
http.setRequestProperty("Content-Language","en-US");
http.setRequestProperty("Content-Type","text/plain");
http.setRequestProperty("Content-Length",String.valueOf(length));
http.setRequestProperty("Cache-Control","no-store");
http.setRequestProperty("Pragma","no-cache");
http.setRequestProperty("Expires","Tue,
1 Jul 1997 00:00:00 GMT");
dove
http è l'oggetto HttpConnection (la connessione
Http aperta con il metodo open)).
Se la richiesta Http è di tipo POST, è
necessario collegare alla connessione Http uno stream
di output per poter inviare i dati al server:
//Apre
la connessione Http
HttpConnection httpConn = (HttpConnection)
Connector.open("http://www.mokabyte.it/MIDPServlet");
//Imposta il tipo richiesta a POST
httpConn.setRequestMethod(HttpConnection.POST);
//Apre uno stream di output per inviare il corpo della
richiesta POST al server
DataOutputStream dos = httpConn.openDataOutputStream();
String requestBody =.........
//Converte il corpo della richiesta in array di byte
byte data[] = requestBody.getBytes();
//Effettua la scrittura del corpo del messaggio Http
Post sullo stream
for( int i=0; i< data.length; i++){
dos.writeByte(data[i]);
}
...
dos.flush();
I campi, della risposta Http ottenuta dal server a seguito
di una richiesta del client, sono accessibili utilizzando
i metodi forniti da HttpConnection. Spesso, infatti,
il client ha necessità di accedere ai campi dell'header
Http, per poter decidere di intraprendere un'azione
piuttosto che un'altra. Ad esempio potrebbe comportarsi
in un determinato modo nel caso ottenga dal server una
risposta positiva mentre potrebbe svolgere altre operazioni
in caso contrario. O ancora, potrebbe controllare la
data dell'ultima modifica effettuata sulla risorsa richiesta
per valutare la necessità di un aggiornamento
dei dati. Nella pratica, quindi, utilizzando connessioni
Http è di fondamentale importanza poter accedere
ai campi dell'header della risposta ottenuta dal server.
Riportiamo di seguito i metodi previsti dal MIDP per
ottenere e manipolare i valori dell'header Http:
public
long getDate()
ritorna il valore del campo data nell'header Http,
il valore tornato è espresso come numero di
millisecondi trascorsi a partire dall'"epoca"
(01-01-1970).
public long getLastModified()
ritorna il valore del campo Last-Modified dell'header
come millisecondi trascorsi dal 01-01-1970
public
long getExpiration()
questo metodo serve ad ottenere il valore del campo
expires dell'header Http. Indica la scadenza della
risorsa richiesta, cioè il momento in cui la
risorsa stessa è da considerarsi non valida
e deve essere nuovamente richiesta al server (il valore
è espresso in millisecondi dall'"epoca"
01-01-1970).
public String getHeaderField(String name)
ritorna il valore, in formato stringa, del campo dell'header
Http indicato da name, null nel caso in cui il campo
sia mancante.
public
int getHeaderFieldInt(String name, int default)
questo metodo ritorna il valore convertito in intero
del campo dell'header identificato da name. Se tale
campo non esiste, oppure non può essere convertito
in intero, ritorna il valore default.
public
long getHeaderFieldDate(String name, long default)
questo metodo fornisce il valore in millisecondidel
campo dell'header identificato da name. Il valore
di tale campo viene parserizzato come una data. Se
il valore del campo richiesto è mancante o
non è una data viene ritornato il valore default.
public
String getHeaderFieldKey(int index)
ritorna il valore del campo dell'header nella posizione
indicata con index, ritorna null se l'indice è
superiore al numero di campi presenti.
public
int getResponseCode()
ritorna lo "status code" del protocollo
Http, ovvero un numero intero associato ad una determinata
risposta ( ad esempio 200 se la risposta è
positiva, 404 se la risorsa richiesta non è
stata trovata, 400 se la richiesta non è stata
mal formulata).
public String getResponseMessage()
ritorna la "reason phrase" dell'Http, cioè
una breve descrizione del codice di risposta (status
code)
(ad esempio: OK nel caso di 200 , NOT FOUND nel caso
di 404, BAD REQUEST se il codice è 400) .
Da ContentConnection, vengono poi ereditati i seguenti
tre metodi che permettono l'accesso a tre campi dell'header
Http di fondamentale importanza:
public String getType()
ritorna il valore del Content-Type dell'header Http.
E' il tipo MIME relativo alla risorsa richiesa (ad
esempio text/plain, text/html, image/png).
public
String getEncoding()
ritorna il Content-Encoding dell'header Http, ed indica
il tipo di codifica applicata al corpo del messaggio
Http, ossia alla risorsa richiesta
public
long getLength()
ritorna il Content-Length Http, ossia la dimensione,
espressa come numero di byte, del corpo della risposta
Http, ovvero della risorsa richiesta
Oltre
ai suddetti metodi HttpConnection contiene tutta una
serie di metodi che permettono di accedere alle informazioni
relative alla connessione Http aperta e alla richiesta
effettuata:
public
String getRequestMethod()
fornisce il valore il tipo di richiesta effettuata,
può assumere i valori GET, POST, HEAD.
public String getRequestProperty(String key)
ritorna il valore di una proprietà della
richiesta Http, impostata con setRequestProperty ed
individuata da key.
public String getURL()
ritorna la stringa rappresentativa dell'URL della
connessione Http aperta (ad esempio: "http://www.mokabyte.it"
).
public
String getProtocol()
indica il tipo di protocollo utilizzato (ad esempio:
http, https).
public
String getHost()
ritorna le informazioni sul campo host contenuti nella
URL (ad esempio: "www.mokabyte.it").
public
String getFile()
ritorna la porzione di URL relativa al file richiesto,
null se tale parte non è presente nella URL
( ad esempio se la URL è http://www.mokabyte.it
ritorna null, ma se la fosse: "http://www.mokabyte.it/index_07_2002.html"
il metodo ritornerebbe "/index_07_2002.html").
public
String getRef()
ritorna la parte di URL relativa ad un riferimento
(anchor) cioè ad una ben precisa sezione di
un documento html. Tale porzione è individuata
nell'URL dopo il carattere "#" ( ad esempio
con una URL del tipo "http://www.mokabyte.it/index_07_2002.html#secton91918273"
il metodo getRef ritorna "secton91918273").
public String getQuery()
questo metodo ritorna la porzione di URL relativa
ad una query. Nell'Http le query sono individuate
dalla parte di URL posta dopo il carattere "?"
e vengono utilizzate per passare parametri a programmi
CGI o servlet, nel formato chiave=valore. Una URL
può contenere query formate da più coppie
chiave=valore che dovranno essere separate dal carattere
":" (ad esempio il metodo getQuery richiamato
su una connessione relativa alla URL:
"http://www.mokabyte.it/MIDPServlet?code=867:number=23:color=red"
ritorna "code=867:number=23:color=red")
public
int getPort()
fornisce il valore della porta indicata nella URL,
80 (il valore di default per l'Http) se nella URL
non viene specificato diversamente ( ad esempio :
se la URL è http://www.mokabyte.it ritorna
80, 8081 se la URL fosse "http://www.mokabyte.it:8081").
Riportiamo
qui sotto, a titolo di esempio, alcune parte di codice
relative ad una richiesta GET ed una POST.
Richiesta
GET
import java.io.*;
import javax.microedition.*;
...
...
String connectionString = "http://www.mokabyte,it";
HttpConnection
httpConn = null;
DataInputStream dis = null;
String message = null;
...
try{
// Apre la connessione ed effettua la richiesta.
// Si tratta di una GET (valore di default)
httpConn = (HttpConnection) Connector.open(connectionString);
// Apre uno stream in input associato alla
connessione
dis = httpConn.openDataInputStream();
int ch;
// Legge dallo stream finchè ci sono
caratteri da leggere
while( (ch = dis.read()) != -1){
message += (char) ch;
}
//Controlla il risultato della richiesta
int statusCode = httpConn.getResponseCode();
// Sulla base della risposta ottenuta dal
server svolge
// una ben determinata azione
switch (statusCode){
case HttpConnection.HTTP_OK:
//Azione da intraprendere nel
caso di risposta 200 OK
break;
case HttpConnection.HTTP_NOT_FOUND:
//Azione da intraprendere nel
caso di risposta 404 NOT FOUND
break;
case HttpConnection.HTTP_MOVED_TEMP:
//Azione da intraprendere nel
caso di risposta 302 MOVED TEMP
break;
case HttpConnection.HTTP_BAD_REQUEST:
//Azione da intraprendere nel
caso di risposta 400 BAD REQUEST
break;
case HttpConnection.HTTP_UNAUTHORIZED:
//Azione da intraprendere nel
caso di risposta 401 UNAUTHORIZED
break;
...
//Gestisce altri tipi di risposta
...
}
...
...
// Chiude la connessione Http e lo stream
di input associato
dos.close();
httpConn.close();
...
}
catch( Exception e){
// Gestisce le eventuali eccezioni
}
Richiesta
POST
import java.io.*;
import javax.microedition.*;
...
...
String connectionString = "http://www.mokabyte,it/MIDPServlet";
HttpConnection
httpConn = null;
DataInputStream dis = null;
DataOutputStream dos = null;
String messageBody = null;
...
try{
// Apre la connessione ed effettua la richiesta
httpConn = (HttpConnection) Connector.open(connectionString);
// Imposta il tipo di richiesta a POST
httpConn.setRequestMethod(HttpConnection.POST);
// Apre uno stream in output associato alla
connessione
dos = httpConn.openDataOutputStream();
...
...
messageBody =...
// Converte il corpo del messaggio Http
in un array di byte
byte data[] = messageBody.getBytes();
// Imposta il valore del Content-Type e
del Content-Length
// nell'header della richiesta Http Post
httpConn.setRequestProperty("Content-Type","text/plain");
httpConn.setRequestProperty("Content-Length",
String.valueOf(data.length));
for(int i=0; i<data.length; i++){
dos.writeByte(data[i]);
}
dos.flush();
//
Controlla il risultato della richiesta
int statusCode = httpConn.getResponseCode();
// Sulla base della risposta ottenuta dal
server svolge
// una ben determinata azione
switch (statusCode){
case HttpConnection.HTTP_OK:
// Azione da intraprendere nel
caso di risposta 200 OK
break;
case HttpConnection.HTTP_NOT_FOUND:
// Azione da intraprendere nel
caso di risposta 404 NOT FOUND
break;
case HttpConnection.HTTP_MOVED_TEMP:
// Azione da intraprendere nel
caso di risposta 302 MOVED TEMP
break;
case HttpConnection.HTTP_BAD_REQUEST:
// Azione da intraprendere nel
caso di risposta 400 BAD REQUEST
break;
case HttpConnection.HTTP_UNAUTHORIZED:
// Azione da intraprendere nel
caso di risposta 401 UNAUTHORIZED
break;
...
// Gestisce altri tipi di risposta
...
}
//
Chiude connessione e stream associato
dos.close();
httpConn.close();
}
catch(Exception e) {
//Gestisce eventuali eccezioni
}
...
...
Riferimenti
MokaByte: Il mondo java embedded
http://www.mokabyte.it/2002/01/j2me_1.htm
MokaByte:
La configurazione CLDC
http://www.mokabyte.it/2002/02/j2me_2.htm
http://developer.java.sun.com/developer/technicalArticles/wireless
Developing Wireless Applications using J2ME[tm] Technology
- Bill Day http://wireless.java.sun.com/getstart/articles/wirelessdev/wirelessdev.pdf
http://java.sun.com/products/midp/
Le
specifiche del protocollo Http 1.1:
http://www.w3.org/Protocols/#Specs
ftp://ftp.isi.edu/in-notes/rfc2616.txt
|