String message = URLEncoder.encode("my message", "UTF-8");
try {
// instantiate the URL object with the target URL of the resource to
// request
URL url = new URL("http://www.example.com/comment");
// instantiate the HttpURLConnection with the URL object - A new
// connection is opened every time by calling the openConnection
// method of the protocol handler for this URL.
// 1. This is the point where the connection is opened.
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// set connection output to true
connection.setDoOutput(true);
// instead of a GET, we're going to send using method="POST"
connection.setRequestMethod("POST");
// instantiate OutputStreamWriter using the output stream, returned
// from getOutputStream, that writes to this connection.
// 2. This is the point where you'll know if the connection was
// successfully established. If an I/O error occurs while creating
// the output stream, you'll see an IOException.
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
// write data to the connection. This is data that you are sending
// to the server
// 3. No. Sending the data is conducted here. We established the
// connection with getOutputStream
writer.write("message=" + message);
// Closes this output stream and releases any system resources
// associated with this stream. At this point, we've sent all the
// data. Only the outputStream is closed at this point, not the
// actual connection
writer.close();
// if there is a response code AND that response code is 200 OK, do
// stuff in the first if block
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// OK
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
// Server returned HTTP error code.
}
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
Le prime 3 risposte alle tue domande sono elencate come commenti incorporati, accanto a ciascun metodo, nell'esempio HTTP POST sopra.
Da getOutputStream :
Restituisce un flusso di output che scrive su questa connessione.
Fondamentalmente, penso che tu abbia una buona comprensione di come funziona, quindi lasciatemi solo ripetere nei termini del profano. getOutputStream
fondamentalmente apre un flusso di connessione , con l'intenzione di scrivere dati sul server. Nell'esempio di codice sopra "messaggio" potrebbe essere un commento che stiamo inviando al server che rappresenta un commento lasciato su un post. Quando vedi getOutputStream
, stai aprendo il flusso di connessione per la scrittura, ma in realtà non scrivi alcun dato finché non chiami writer.write("message=" + message);
.
Da getInputStream () :
Restituisce un flusso di input che legge da questa connessione aperta. È possibile generare SocketTimeoutException durante la lettura dal flusso di input restituito se il timeout di lettura scade prima che i dati siano disponibili per la lettura.
getInputStream
fa il contrario. Ad esempio getOutputStream
, apre anche un flusso di connessione , ma l'intento è leggere i dati dal server, non scrivere su di esso. Se la connessione o l'apertura del flusso falliscono, vedrai a SocketTimeoutException
.
Che ne dici di getInputStream? Dato che sono in grado di ottenere la risposta solo su getInputStream, significa che non ho ancora inviato alcuna richiesta a getOutputStream ma che semplicemente stabilisce una connessione?
Tieni presente che l'invio di una richiesta e l'invio di dati sono due operazioni diverse. Quando si richiama getOutputStream o getInputStream url.openConnection()
, si invia una richiesta al server per stabilire una connessione. Si verifica una stretta di mano in cui il server ti restituisce un riconoscimento dell'avvenuta connessione. È quindi in quel momento che sei pronto per inviare o ricevere dati. Pertanto, non è necessario chiamare getOutputStream per stabilire una connessione per aprire uno stream, a meno che lo scopo per effettuare la richiesta non sia inviare dati.
In parole povere, fare una getInputStream
richiesta equivale a fare una telefonata a casa del tuo amico per dire "Ehi, va bene se vengo e prendo in prestito quella coppia di morsa?" e il tuo amico stabilisce la stretta di mano dicendo "Certo! Vieni a prenderla". Quindi, a quel punto, viene stabilita la connessione, cammini a casa del tuo amico, bussi alla porta, richiedi le morsa e tornerai a casa tua.
Usare un esempio simile getOutputStream
implicherebbe chiamare il tuo amico e dire "Ehi, ho quei soldi che ti devo, posso inviarti"? Il tuo amico, bisognoso di soldi e malato dentro che l'hai tenuto per così tanto tempo, dice "Certo, vieni da te bastardo a buon mercato". Quindi vai a casa del tuo amico e "POST" i soldi per lui. Ti butta fuori e torni a casa tua.
Ora, proseguendo con l'esempio del profano, diamo un'occhiata ad alcune eccezioni. Se hai chiamato il tuo amico e lui non era a casa, potrebbe essere un errore 500. Se hai chiamato e hai ricevuto un messaggio di numero disconnesso perché il tuo amico è stanco di prendere in prestito denaro per tutto il tempo, questa è una pagina 404 non trovata. Se il tuo telefono è morto perché non hai pagato il conto, potrebbe trattarsi di un'eccezione IOException. (NOTA: questa sezione potrebbe non essere corretta al 100%. Ha lo scopo di darti un'idea generale di ciò che sta accadendo in termini di profani.)
Domanda n. 5:
Sì, hai ragione nel dire che openConnection crea semplicemente un nuovo oggetto connessione ma non lo stabilisce. La connessione viene stabilita quando si chiama getInputStream o getOutputStream.
openConnection
crea un nuovo oggetto connessione. Da javadocs URL.openConnection :
Una nuova connessione viene aperta ogni volta chiamando il metodo openConnection del gestore del protocollo per questo URL.
La connessione viene stabilita quando si chiama openConnection e InputStream, OutputStream o entrambi vengono chiamati quando vengono istanziati.
Domanda n. 6 :
Per misurare l'overhead, generalmente avvolgo un codice di temporizzazione molto semplice attorno all'intero blocco di connessione, in questo modo:
long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );
// run the above example code here
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );
Sono sicuro che esistono metodi più avanzati per misurare i tempi e le spese generali della richiesta, ma in genere questo è sufficiente per le mie esigenze.
Per informazioni sulla chiusura delle connessioni, di cui non hai chiesto informazioni, vedi In Java quando viene chiusa una connessione URL? .